1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.uucp)
5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
8 This file is part of the libiberty library.
9 Libiberty is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 In addition to the permissions in the GNU Library General Public
15 License, the Free Software Foundation gives you unlimited permission
16 to link the compiled version of this file into combinations with other
17 programs, and to distribute those combinations without any restriction
18 coming from the use of this file. (The Library Public License
19 restrictions do apply in other respects; for example, they cover
20 modification of the file, and distribution when not linked into a
23 Libiberty is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 Library General Public License for more details.
28 You should have received a copy of the GNU Library General Public
29 License along with libiberty; see the file COPYING.LIB. If
30 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
31 Boston, MA 02110-1301, USA. */
33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
35 This file imports xmalloc and xrealloc, which are like malloc and
36 realloc except that they generate a fatal error if there is no
39 /* This file lives in both GCC and libiberty. When making changes, please
40 try not to break either. */
46 #include "safe-ctype.h"
48 #include <sys/types.h>
60 #undef CURRENT_DEMANGLING_STYLE
61 #define CURRENT_DEMANGLING_STYLE work->options
63 #include "libiberty.h"
65 #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
)
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. '___elabs' and
899 '___elabb' add only 2 chars, but they occur only once. */
900 len0
= strlen (mangled
) + 2 + 1;
901 demangled
= XNEWVEC (char, len0
);
907 /* Convert name, which is always lower-case. */
912 while (ISLOWER(*p
) || ISDIGIT (*p
)
913 || (p
[0] == '_' && (ISLOWER (p
[1]) || ISDIGIT (p
[1]))));
915 else if (p
[0] == 'O')
917 static const char * const operators
[][2] =
918 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
919 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
920 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
921 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
922 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
923 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
924 {"Oexpon", "**"}, {NULL
, NULL
}};
927 for (k
= 0; operators
[k
][0]; k
++)
929 int l
= strlen (operators
[k
][0]);
930 if (!strncmp (p
, operators
[k
][0], l
))
933 l
= strlen (operators
[k
][1]);
935 memcpy (d
, operators
[k
][1], l
);
941 /* Operator not found. */
942 if (!operators
[k
][0])
947 /* Not a GNAT encoding. */
956 /* Standard separator. Handled first. */
963 while (ISDIGIT (*p
) || (p
[0] == '_' && ISDIGIT (p
[1])));
965 else if (*p
== '_' && !strcmp (p
+ 1, "elabb"))
967 memcpy (d
, "'Elab_Body", 10);
971 else if (*p
== '_' && !strcmp (p
+ 1, "elabs"))
973 memcpy (d
, "'Elab_Spec", 10);
983 else if (p
[1] == 'B' || p
[1] == 'E')
985 /* Entry Body or barrier Evaluation. */
989 if (p
[0] == 's' && p
[1] == 0)
998 if (p
[0] == 'T' && p
[1] == 'K')
1000 if (p
[2] == 'B' && p
[3] == 0)
1002 /* Subprogram for task body. */
1005 else if (p
[2] == '_' && p
[3] == '_')
1007 /* Inner declarations in a task. */
1015 if ((p
[0] == 'P' || p
[0] == 'N') && p
[1] == 0)
1017 /* Protected type subprogram. */
1020 if (p
[0] == 'E' && p
[1] == 0)
1022 /* Exception name. */
1025 if (*p
== 'N' || *p
== 'S')
1027 /* Enumerated type name table. */
1033 if (p
[1] == 'n' || p
[1] == 'b')
1038 if (p
[0] == '.' && ISDIGIT (p
[1]))
1040 /* Nested subprogram. */
1042 while (ISDIGIT (*p
))
1047 /* End of mangled name. */
1057 len0
= strlen (mangled
);
1058 demangled
= XNEWVEC (char, len0
+ 3);
1060 if (mangled
[0] == '<')
1061 strcpy (demangled
, mangled
);
1063 sprintf (demangled
, "<%s>", mangled
);
1068 /* This function performs most of what cplus_demangle use to do, but
1069 to be able to demangle a name with a B, K or n code, we need to
1070 have a longer term memory of what types have been seen. The original
1071 now initializes and cleans up the squangle code info, while internal
1072 calls go directly to this routine to avoid resetting that info. */
1075 internal_cplus_demangle (struct work_stuff
*work
, const char *mangled
)
1080 char *demangled
= NULL
;
1082 s1
= work
->constructor
;
1083 s2
= work
->destructor
;
1084 s3
= work
->static_type
;
1085 s4
= work
->type_quals
;
1086 work
->constructor
= work
->destructor
= 0;
1087 work
->type_quals
= TYPE_UNQUALIFIED
;
1088 work
->dllimported
= 0;
1090 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
1092 string_init (&decl
);
1094 /* First check to see if gnu style demangling is active and if the
1095 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1096 recognize one of the gnu special forms rather than looking for a
1097 standard prefix. In particular, don't worry about whether there
1098 is a "__" string in the mangled string. Consider "_$_5__foo" for
1101 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
1103 success
= gnu_special (work
, &mangled
, &decl
);
1107 success
= demangle_prefix (work
, &mangled
, &decl
);
1109 if (success
&& (*mangled
!= '\0'))
1111 success
= demangle_signature (work
, &mangled
, &decl
);
1113 if (work
->constructor
== 2)
1115 string_prepend (&decl
, "global constructors keyed to ");
1116 work
->constructor
= 0;
1118 else if (work
->destructor
== 2)
1120 string_prepend (&decl
, "global destructors keyed to ");
1121 work
->destructor
= 0;
1123 else if (work
->dllimported
== 1)
1125 string_prepend (&decl
, "import stub for ");
1126 work
->dllimported
= 0;
1128 demangled
= mop_up (work
, &decl
, success
);
1130 work
->constructor
= s1
;
1131 work
->destructor
= s2
;
1132 work
->static_type
= s3
;
1133 work
->type_quals
= s4
;
1138 /* Clear out and squangling related storage */
1140 squangle_mop_up (struct work_stuff
*work
)
1142 /* clean up the B and K type mangling types. */
1143 forget_B_and_K_types (work
);
1144 if (work
-> btypevec
!= NULL
)
1146 free ((char *) work
-> btypevec
);
1148 if (work
-> ktypevec
!= NULL
)
1150 free ((char *) work
-> ktypevec
);
1155 /* Copy the work state and storage. */
1158 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1162 delete_work_stuff (to
);
1164 /* Shallow-copy scalars. */
1165 memcpy (to
, from
, sizeof (*to
));
1167 /* Deep-copy dynamic storage. */
1168 if (from
->typevec_size
)
1169 to
->typevec
= XNEWVEC (char *, from
->typevec_size
);
1171 for (i
= 0; i
< from
->ntypes
; i
++)
1173 int len
= strlen (from
->typevec
[i
]) + 1;
1175 to
->typevec
[i
] = XNEWVEC (char, len
);
1176 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1180 to
->ktypevec
= XNEWVEC (char *, from
->ksize
);
1182 for (i
= 0; i
< from
->numk
; i
++)
1184 int len
= strlen (from
->ktypevec
[i
]) + 1;
1186 to
->ktypevec
[i
] = XNEWVEC (char, len
);
1187 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1191 to
->btypevec
= XNEWVEC (char *, from
->bsize
);
1193 for (i
= 0; i
< from
->numb
; i
++)
1195 int len
= strlen (from
->btypevec
[i
]) + 1;
1197 to
->btypevec
[i
] = XNEWVEC (char , len
);
1198 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1201 if (from
->ntmpl_args
)
1202 to
->tmpl_argvec
= XNEWVEC (char *, from
->ntmpl_args
);
1204 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1206 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1208 to
->tmpl_argvec
[i
] = XNEWVEC (char, len
);
1209 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1212 if (from
->previous_argument
)
1214 to
->previous_argument
= XNEW (string
);
1215 string_init (to
->previous_argument
);
1216 string_appends (to
->previous_argument
, from
->previous_argument
);
1221 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1224 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1226 /* Discard the remembered types, if any. */
1228 forget_types (work
);
1229 if (work
-> typevec
!= NULL
)
1231 free ((char *) work
-> typevec
);
1232 work
-> typevec
= NULL
;
1233 work
-> typevec_size
= 0;
1235 if (work
->tmpl_argvec
)
1239 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1240 if (work
->tmpl_argvec
[i
])
1241 free ((char*) work
->tmpl_argvec
[i
]);
1243 free ((char*) work
->tmpl_argvec
);
1244 work
->tmpl_argvec
= NULL
;
1246 if (work
->previous_argument
)
1248 string_delete (work
->previous_argument
);
1249 free ((char*) work
->previous_argument
);
1250 work
->previous_argument
= NULL
;
1255 /* Delete all dynamic storage in work_stuff. */
1257 delete_work_stuff (struct work_stuff
*work
)
1259 delete_non_B_K_work_stuff (work
);
1260 squangle_mop_up (work
);
1264 /* Clear out any mangled storage */
1267 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1269 char *demangled
= NULL
;
1271 delete_non_B_K_work_stuff (work
);
1273 /* If demangling was successful, ensure that the demangled string is null
1274 terminated and return it. Otherwise, free the demangling decl. */
1278 string_delete (declp
);
1282 string_appendn (declp
, "", 1);
1283 demangled
= declp
->b
;
1292 demangle_signature -- demangle the signature part of a mangled name
1297 demangle_signature (struct work_stuff *work, const char **mangled,
1302 Consume and demangle the signature portion of the mangled name.
1304 DECLP is the string where demangled output is being built. At
1305 entry it contains the demangled root name from the mangled name
1306 prefix. I.E. either a demangled operator name or the root function
1307 name. In some special cases, it may contain nothing.
1309 *MANGLED points to the current unconsumed location in the mangled
1310 name. As tokens are consumed and demangling is performed, the
1311 pointer is updated to continuously point at the next token to
1314 Demangling GNU style mangled names is nasty because there is no
1315 explicit token that marks the start of the outermost function
1319 demangle_signature (struct work_stuff
*work
,
1320 const char **mangled
, string
*declp
)
1324 int expect_func
= 0;
1325 int expect_return_type
= 0;
1326 const char *oldmangled
= NULL
;
1330 while (success
&& (**mangled
!= '\0'))
1335 oldmangled
= *mangled
;
1336 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1338 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1339 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1345 oldmangled
= *mangled
;
1346 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1347 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1355 /* Static member function */
1356 if (oldmangled
== NULL
)
1358 oldmangled
= *mangled
;
1361 work
-> static_type
= 1;
1367 work
->type_quals
|= code_for_qualifier (**mangled
);
1369 /* a qualified member function */
1370 if (oldmangled
== NULL
)
1371 oldmangled
= *mangled
;
1376 /* Local class name follows after "Lnnn_" */
1379 while (**mangled
&& (**mangled
!= '_'))
1390 case '0': case '1': case '2': case '3': case '4':
1391 case '5': case '6': case '7': case '8': case '9':
1392 if (oldmangled
== NULL
)
1394 oldmangled
= *mangled
;
1396 work
->temp_start
= -1; /* uppermost call to demangle_class */
1397 success
= demangle_class (work
, mangled
, declp
);
1400 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1402 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1404 /* EDG and others will have the "F", so we let the loop cycle
1405 if we are looking at one. */
1406 if (**mangled
!= 'F')
1415 success
= do_type (work
, mangled
, &s
);
1418 string_append (&s
, SCOPE_STRING (work
));
1419 string_prepends (declp
, &s
);
1429 /* ARM/HP style demangling includes a specific 'F' character after
1430 the class name. For GNU style, it is just implied. So we can
1431 safely just consume any 'F' at this point and be compatible
1432 with either style. */
1438 /* For lucid/ARM/HP style we have to forget any types we might
1439 have remembered up to this point, since they were not argument
1440 types. GNU style considers all types seen as available for
1441 back references. See comment in demangle_args() */
1443 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1445 forget_types (work
);
1447 success
= demangle_args (work
, mangled
, declp
);
1448 /* After picking off the function args, we expect to either
1449 find the function return type (preceded by an '_') or the
1450 end of the string. */
1451 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1454 /* At this level, we do not care about the return type. */
1455 success
= do_type (work
, mangled
, &tname
);
1456 string_delete (&tname
);
1463 string_init(&trawname
);
1464 string_init(&tname
);
1465 if (oldmangled
== NULL
)
1467 oldmangled
= *mangled
;
1469 success
= demangle_template (work
, mangled
, &tname
,
1473 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1475 string_append (&tname
, SCOPE_STRING (work
));
1477 string_prepends(declp
, &tname
);
1478 if (work
-> destructor
& 1)
1480 string_prepend (&trawname
, "~");
1481 string_appends (declp
, &trawname
);
1482 work
->destructor
-= 1;
1484 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1486 string_appends (declp
, &trawname
);
1487 work
->constructor
-= 1;
1489 string_delete(&trawname
);
1490 string_delete(&tname
);
1496 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1498 /* Read the return type. */
1502 success
= do_type (work
, mangled
, &return_type
);
1503 APPEND_BLANK (&return_type
);
1505 string_prepends (declp
, &return_type
);
1506 string_delete (&return_type
);
1510 /* At the outermost level, we cannot have a return type specified,
1511 so if we run into another '_' at this point we are dealing with
1512 a mangled name that is either bogus, or has been mangled by
1513 some algorithm we don't know how to deal with. So just
1514 reject the entire demangling. */
1515 /* However, "_nnn" is an expected suffix for alternate entry point
1516 numbered nnn for a function, with HP aCC, so skip over that
1517 without reporting failure. pai/1997-09-04 */
1521 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1529 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1531 /* A G++ template function. Read the template arguments. */
1532 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1534 if (!(work
->constructor
& 1))
1535 expect_return_type
= 1;
1544 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1546 /* Assume we have stumbled onto the first outermost function
1547 argument token, and start processing args. */
1549 success
= demangle_args (work
, mangled
, declp
);
1553 /* Non-GNU demanglers use a specific token to mark the start
1554 of the outermost function argument tokens. Typically 'F',
1555 for ARM/HP-demangling, for example. So if we find something
1556 we are not prepared for, it must be an error. */
1562 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1565 if (success
&& expect_func
)
1568 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1570 forget_types (work
);
1572 success
= demangle_args (work
, mangled
, declp
);
1573 /* Since template include the mangling of their return types,
1574 we must set expect_func to 0 so that we don't try do
1575 demangle more arguments the next time we get here. */
1580 if (success
&& !func_done
)
1582 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1584 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1585 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1586 first case, and need to ensure that the '(void)' gets added to
1587 the current declp. Note that with ARM/HP, the first case
1588 represents the name of a static data member 'foo::bar',
1589 which is in the current declp, so we leave it alone. */
1590 success
= demangle_args (work
, mangled
, declp
);
1593 if (success
&& PRINT_ARG_TYPES
)
1595 if (work
->static_type
)
1596 string_append (declp
, " static");
1597 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1599 APPEND_BLANK (declp
);
1600 string_append (declp
, qualifier_string (work
->type_quals
));
1610 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1615 if (work
-> static_type
)
1617 string_append (declp
, *mangled
+ 1);
1618 *mangled
+= strlen (*mangled
);
1623 success
= demangle_args (work
, mangled
, declp
);
1631 demangle_template_template_parm (struct work_stuff
*work
,
1632 const char **mangled
, string
*tname
)
1640 string_append (tname
, "template <");
1641 /* get size of template parameter list */
1642 if (get_count (mangled
, &r
))
1644 for (i
= 0; i
< r
; i
++)
1648 string_append (tname
, ", ");
1651 /* Z for type parameters */
1652 if (**mangled
== 'Z')
1655 string_append (tname
, "class");
1657 /* z for template parameters */
1658 else if (**mangled
== 'z')
1662 demangle_template_template_parm (work
, mangled
, tname
);
1670 /* temp is initialized in do_type */
1671 success
= do_type (work
, mangled
, &temp
);
1674 string_appends (tname
, &temp
);
1676 string_delete(&temp
);
1686 if (tname
->p
[-1] == '>')
1687 string_append (tname
, " ");
1688 string_append (tname
, "> class");
1693 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1694 string
*s
, type_kind_t tk
)
1696 int need_operator
= 0;
1700 string_appendn (s
, "(", 1);
1702 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1711 len
= strlen (*mangled
);
1713 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1715 size_t l
= strlen (optable
[i
].in
);
1718 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1720 string_appendn (s
, " ", 1);
1721 string_append (s
, optable
[i
].out
);
1722 string_appendn (s
, " ", 1);
1735 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1738 if (**mangled
!= 'W')
1742 string_appendn (s
, ")", 1);
1750 demangle_integral_value (struct work_stuff
*work
,
1751 const char **mangled
, string
*s
)
1755 if (**mangled
== 'E')
1756 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1757 else if (**mangled
== 'Q' || **mangled
== 'K')
1758 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1763 /* By default, we let the number decide whether we shall consume an
1765 int multidigit_without_leading_underscore
= 0;
1766 int leave_following_underscore
= 0;
1770 if (**mangled
== '_')
1772 if (mangled
[0][1] == 'm')
1774 /* Since consume_count_with_underscores does not handle the
1775 `m'-prefix we must do it here, using consume_count and
1776 adjusting underscores: we have to consume the underscore
1777 matching the prepended one. */
1778 multidigit_without_leading_underscore
= 1;
1779 string_appendn (s
, "-", 1);
1784 /* Do not consume a following underscore;
1785 consume_count_with_underscores will consume what
1786 should be consumed. */
1787 leave_following_underscore
= 1;
1792 /* Negative numbers are indicated with a leading `m'. */
1793 if (**mangled
== 'm')
1795 string_appendn (s
, "-", 1);
1798 /* Since consume_count_with_underscores does not handle
1799 multi-digit numbers that do not start with an underscore,
1800 and this number can be an integer template parameter,
1801 we have to call consume_count. */
1802 multidigit_without_leading_underscore
= 1;
1803 /* These multi-digit numbers never end on an underscore,
1804 so if there is one then don't eat it. */
1805 leave_following_underscore
= 1;
1808 /* We must call consume_count if we expect to remove a trailing
1809 underscore, since consume_count_with_underscores expects
1810 the leading underscore (that we consumed) if it is to handle
1811 multi-digit numbers. */
1812 if (multidigit_without_leading_underscore
)
1813 value
= consume_count (mangled
);
1815 value
= consume_count_with_underscores (mangled
);
1819 char buf
[INTBUF_SIZE
];
1820 sprintf (buf
, "%d", value
);
1821 string_append (s
, buf
);
1823 /* Numbers not otherwise delimited, might have an underscore
1824 appended as a delimeter, which we should skip.
1826 ??? This used to always remove a following underscore, which
1827 is wrong. If other (arbitrary) cases are followed by an
1828 underscore, we need to do something more radical. */
1830 if ((value
> 9 || multidigit_without_leading_underscore
)
1831 && ! leave_following_underscore
1832 && **mangled
== '_')
1843 /* Demangle the real value in MANGLED. */
1846 demangle_real_value (struct work_stuff
*work
,
1847 const char **mangled
, string
*s
)
1849 if (**mangled
== 'E')
1850 return demangle_expression (work
, mangled
, s
, tk_real
);
1852 if (**mangled
== 'm')
1854 string_appendn (s
, "-", 1);
1857 while (ISDIGIT ((unsigned char)**mangled
))
1859 string_appendn (s
, *mangled
, 1);
1862 if (**mangled
== '.') /* fraction */
1864 string_appendn (s
, ".", 1);
1866 while (ISDIGIT ((unsigned char)**mangled
))
1868 string_appendn (s
, *mangled
, 1);
1872 if (**mangled
== 'e') /* exponent */
1874 string_appendn (s
, "e", 1);
1876 while (ISDIGIT ((unsigned char)**mangled
))
1878 string_appendn (s
, *mangled
, 1);
1887 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
1888 string
*s
, type_kind_t tk
)
1892 if (**mangled
== 'Y')
1894 /* The next argument is a template parameter. */
1898 idx
= consume_count_with_underscores (mangled
);
1900 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1901 || consume_count_with_underscores (mangled
) == -1)
1903 if (work
->tmpl_argvec
)
1904 string_append (s
, work
->tmpl_argvec
[idx
]);
1906 string_append_template_idx (s
, idx
);
1908 else if (tk
== tk_integral
)
1909 success
= demangle_integral_value (work
, mangled
, s
);
1910 else if (tk
== tk_char
)
1914 if (**mangled
== 'm')
1916 string_appendn (s
, "-", 1);
1919 string_appendn (s
, "'", 1);
1920 val
= consume_count(mangled
);
1927 string_appendn (s
, &tmp
[0], 1);
1928 string_appendn (s
, "'", 1);
1931 else if (tk
== tk_bool
)
1933 int val
= consume_count (mangled
);
1935 string_appendn (s
, "false", 5);
1937 string_appendn (s
, "true", 4);
1941 else if (tk
== tk_real
)
1942 success
= demangle_real_value (work
, mangled
, s
);
1943 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1945 if (**mangled
== 'Q')
1946 success
= demangle_qualified (work
, mangled
, s
,
1951 int symbol_len
= consume_count (mangled
);
1952 if (symbol_len
== -1)
1954 if (symbol_len
== 0)
1955 string_appendn (s
, "0", 1);
1958 char *p
= XNEWVEC (char, symbol_len
+ 1), *q
;
1959 strncpy (p
, *mangled
, symbol_len
);
1960 p
[symbol_len
] = '\0';
1961 /* We use cplus_demangle here, rather than
1962 internal_cplus_demangle, because the name of the entity
1963 mangled here does not make use of any of the squangling
1964 or type-code information we have built up thus far; it is
1965 mangled independently. */
1966 q
= cplus_demangle (p
, work
->options
);
1967 if (tk
== tk_pointer
)
1968 string_appendn (s
, "&", 1);
1969 /* FIXME: Pointer-to-member constants should get a
1970 qualifying class name here. */
1973 string_append (s
, q
);
1977 string_append (s
, p
);
1980 *mangled
+= symbol_len
;
1987 /* Demangle the template name in MANGLED. The full name of the
1988 template (e.g., S<int>) is placed in TNAME. The name without the
1989 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1990 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1991 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1992 the template is remembered in the list of back-referenceable
1996 demangle_template (struct work_stuff
*work
, const char **mangled
,
1997 string
*tname
, string
*trawname
,
1998 int is_type
, int remember
)
2004 int is_java_array
= 0;
2010 /* get template name */
2011 if (**mangled
== 'z')
2017 idx
= consume_count_with_underscores (mangled
);
2019 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2020 || consume_count_with_underscores (mangled
) == -1)
2023 if (work
->tmpl_argvec
)
2025 string_append (tname
, work
->tmpl_argvec
[idx
]);
2027 string_append (trawname
, work
->tmpl_argvec
[idx
]);
2031 string_append_template_idx (tname
, idx
);
2033 string_append_template_idx (trawname
, idx
);
2038 if ((r
= consume_count (mangled
)) <= 0
2039 || (int) strlen (*mangled
) < r
)
2043 is_java_array
= (work
-> options
& DMGL_JAVA
)
2044 && strncmp (*mangled
, "JArray1Z", 8) == 0;
2045 if (! is_java_array
)
2047 string_appendn (tname
, *mangled
, r
);
2050 string_appendn (trawname
, *mangled
, r
);
2055 string_append (tname
, "<");
2056 /* get size of template parameter list */
2057 if (!get_count (mangled
, &r
))
2063 /* Create an array for saving the template argument values. */
2064 work
->tmpl_argvec
= XNEWVEC (char *, r
);
2065 work
->ntmpl_args
= r
;
2066 for (i
= 0; i
< r
; i
++)
2067 work
->tmpl_argvec
[i
] = 0;
2069 for (i
= 0; i
< r
; i
++)
2073 string_append (tname
, ", ");
2075 /* Z for type parameters */
2076 if (**mangled
== 'Z')
2079 /* temp is initialized in do_type */
2080 success
= do_type (work
, mangled
, &temp
);
2083 string_appends (tname
, &temp
);
2087 /* Save the template argument. */
2088 int len
= temp
.p
- temp
.b
;
2089 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2090 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2091 work
->tmpl_argvec
[i
][len
] = '\0';
2094 string_delete(&temp
);
2100 /* z for template parameters */
2101 else if (**mangled
== 'z')
2105 success
= demangle_template_template_parm (work
, mangled
, tname
);
2108 && (r2
= consume_count (mangled
)) > 0
2109 && (int) strlen (*mangled
) >= r2
)
2111 string_append (tname
, " ");
2112 string_appendn (tname
, *mangled
, r2
);
2115 /* Save the template argument. */
2117 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2118 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2119 work
->tmpl_argvec
[i
][len
] = '\0';
2133 /* otherwise, value parameter */
2135 /* temp is initialized in do_type */
2136 success
= do_type (work
, mangled
, &temp
);
2137 string_delete(&temp
);
2149 success
= demangle_template_value_parm (work
, mangled
, s
,
2150 (type_kind_t
) success
);
2162 int len
= s
->p
- s
->b
;
2163 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2164 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2165 work
->tmpl_argvec
[i
][len
] = '\0';
2167 string_appends (tname
, s
);
2175 string_append (tname
, "[]");
2179 if (tname
->p
[-1] == '>')
2180 string_append (tname
, " ");
2181 string_append (tname
, ">");
2184 if (is_type
&& remember
)
2186 const int bindex
= register_Btype (work
);
2187 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2191 if (work -> static_type)
2193 string_append (declp, *mangled + 1);
2194 *mangled += strlen (*mangled);
2199 success = demangle_args (work, mangled, declp);
2207 arm_pt (struct work_stuff
*work
, const char *mangled
,
2208 int n
, const char **anchor
, const char **args
)
2210 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2211 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2212 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2215 *args
= *anchor
+ 6;
2216 len
= consume_count (args
);
2219 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2225 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2227 if ((*anchor
= strstr (mangled
, "__tm__"))
2228 || (*anchor
= strstr (mangled
, "__ps__"))
2229 || (*anchor
= strstr (mangled
, "__pt__")))
2232 *args
= *anchor
+ 6;
2233 len
= consume_count (args
);
2236 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2242 else if ((*anchor
= strstr (mangled
, "__S")))
2245 *args
= *anchor
+ 3;
2246 len
= consume_count (args
);
2249 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2261 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2262 int n
, string
*declp
)
2266 const char *e
= *mangled
+ n
;
2269 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2271 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2273 char *start_spec_args
= NULL
;
2276 /* First check for and omit template specialization pseudo-arguments,
2277 such as in "Spec<#1,#1.*>" */
2278 start_spec_args
= strchr (*mangled
, '<');
2279 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2280 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2282 string_appendn (declp
, *mangled
, n
);
2283 (*mangled
) += n
+ 1;
2285 if (work
->temp_start
== -1) /* non-recursive call */
2286 work
->temp_start
= declp
->p
- declp
->b
;
2288 /* We want to unconditionally demangle parameter types in
2289 template parameters. */
2290 hold_options
= work
->options
;
2291 work
->options
|= DMGL_PARAMS
;
2293 string_append (declp
, "<");
2296 string_delete (&arg
);
2300 /* 'T' signals a type parameter */
2302 if (!do_type (work
, mangled
, &arg
))
2303 goto hpacc_template_args_done
;
2308 /* 'U' or 'S' signals an integral value */
2309 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2310 goto hpacc_template_args_done
;
2314 /* 'A' signals a named constant expression (literal) */
2315 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2316 goto hpacc_template_args_done
;
2320 /* Today, 1997-09-03, we have only the above types
2321 of template parameters */
2322 /* FIXME: maybe this should fail and return null */
2323 goto hpacc_template_args_done
;
2325 string_appends (declp
, &arg
);
2326 /* Check if we're at the end of template args.
2327 0 if at end of static member of template class,
2328 _ if done with template args for a function */
2329 if ((**mangled
== '\000') || (**mangled
== '_'))
2332 string_append (declp
, ",");
2334 hpacc_template_args_done
:
2335 string_append (declp
, ">");
2336 string_delete (&arg
);
2337 if (**mangled
== '_')
2339 work
->options
= hold_options
;
2342 /* ARM template? (Also handles HP cfront extensions) */
2343 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2349 string_appendn (declp
, *mangled
, p
- *mangled
);
2350 if (work
->temp_start
== -1) /* non-recursive call */
2351 work
->temp_start
= declp
->p
- declp
->b
;
2353 /* We want to unconditionally demangle parameter types in
2354 template parameters. */
2355 hold_options
= work
->options
;
2356 work
->options
|= DMGL_PARAMS
;
2358 string_append (declp
, "<");
2359 /* should do error checking here */
2361 string_delete (&arg
);
2363 /* Check for type or literal here */
2366 /* HP cfront extensions to ARM for template args */
2367 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2368 /* FIXME: We handle only numeric literals for HP cfront */
2370 /* A typed constant value follows */
2372 if (!do_type (work
, &args
, &type_str
))
2373 goto cfront_template_args_done
;
2374 string_append (&arg
, "(");
2375 string_appends (&arg
, &type_str
);
2376 string_delete (&type_str
);
2377 string_append (&arg
, ")");
2379 goto cfront_template_args_done
;
2381 /* Now snarf a literal value following 'L' */
2382 if (!snarf_numeric_literal (&args
, &arg
))
2383 goto cfront_template_args_done
;
2387 /* Snarf a literal following 'L' */
2389 if (!snarf_numeric_literal (&args
, &arg
))
2390 goto cfront_template_args_done
;
2393 /* Not handling other HP cfront stuff */
2395 const char* old_args
= args
;
2396 if (!do_type (work
, &args
, &arg
))
2397 goto cfront_template_args_done
;
2399 /* Fail if we didn't make any progress: prevent infinite loop. */
2400 if (args
== old_args
)
2402 work
->options
= hold_options
;
2407 string_appends (declp
, &arg
);
2408 string_append (declp
, ",");
2410 cfront_template_args_done
:
2411 string_delete (&arg
);
2413 --declp
->p
; /* remove extra comma */
2414 string_append (declp
, ">");
2415 work
->options
= hold_options
;
2417 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2418 && (*mangled
)[9] == 'N'
2419 && (*mangled
)[8] == (*mangled
)[10]
2420 && strchr (cplus_markers
, (*mangled
)[8]))
2422 /* A member of the anonymous namespace. */
2423 string_append (declp
, "{anonymous}");
2427 if (work
->temp_start
== -1) /* non-recursive call only */
2428 work
->temp_start
= 0; /* disable in recursive calls */
2429 string_appendn (declp
, *mangled
, n
);
2434 /* Extract a class name, possibly a template with arguments, from the
2435 mangled string; qualifiers, local class indicators, etc. have
2436 already been dealt with */
2439 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2445 n
= consume_count (mangled
);
2448 if ((int) strlen (*mangled
) >= n
)
2450 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2461 demangle_class -- demangle a mangled class sequence
2466 demangle_class (struct work_stuff *work, const char **mangled,
2471 DECLP points to the buffer into which demangling is being done.
2473 *MANGLED points to the current token to be demangled. On input,
2474 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2475 On exit, it points to the next token after the mangled class on
2476 success, or the first unconsumed token on failure.
2478 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2479 we are demangling a constructor or destructor. In this case
2480 we prepend "class::class" or "class::~class" to DECLP.
2482 Otherwise, we prepend "class::" to the current DECLP.
2484 Reset the constructor/destructor flags once they have been
2485 "consumed". This allows demangle_class to be called later during
2486 the same demangling, to do normal class demangling.
2488 Returns 1 if demangling is successful, 0 otherwise.
2493 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2498 char *save_class_name_end
= 0;
2500 string_init (&class_name
);
2501 btype
= register_Btype (work
);
2502 if (demangle_class_name (work
, mangled
, &class_name
))
2504 save_class_name_end
= class_name
.p
;
2505 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2507 /* adjust so we don't include template args */
2508 if (work
->temp_start
&& (work
->temp_start
!= -1))
2510 class_name
.p
= class_name
.b
+ work
->temp_start
;
2512 string_prepends (declp
, &class_name
);
2513 if (work
-> destructor
& 1)
2515 string_prepend (declp
, "~");
2516 work
-> destructor
-= 1;
2520 work
-> constructor
-= 1;
2523 class_name
.p
= save_class_name_end
;
2524 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2525 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2526 string_prepend (declp
, SCOPE_STRING (work
));
2527 string_prepends (declp
, &class_name
);
2530 string_delete (&class_name
);
2535 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2536 the rightmost guess.
2538 Find the correct "__"-sequence where the function name ends and the
2539 signature starts, which is ambiguous with GNU mangling.
2540 Call demangle_signature here, so we can make sure we found the right
2541 one; *mangled will be consumed so caller will not make further calls to
2542 demangle_signature. */
2545 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2546 string
*declp
, const char *scan
)
2548 const char *mangle_init
= *mangled
;
2551 struct work_stuff work_init
;
2553 if (*(scan
+ 2) == '\0')
2556 /* Do not iterate for some demangling modes, or if there's only one
2557 "__"-sequence. This is the normal case. */
2558 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2559 || strstr (scan
+ 2, "__") == NULL
)
2560 return demangle_function_name (work
, mangled
, declp
, scan
);
2562 /* Save state so we can restart if the guess at the correct "__" was
2564 string_init (&decl_init
);
2565 string_appends (&decl_init
, declp
);
2566 memset (&work_init
, 0, sizeof work_init
);
2567 work_stuff_copy_to_from (&work_init
, work
);
2569 /* Iterate over occurrences of __, allowing names and types to have a
2570 "__" sequence in them. We must start with the first (not the last)
2571 occurrence, since "__" most often occur between independent mangled
2572 parts, hence starting at the last occurence inside a signature
2573 might get us a "successful" demangling of the signature. */
2577 if (demangle_function_name (work
, mangled
, declp
, scan
))
2579 success
= demangle_signature (work
, mangled
, declp
);
2584 /* Reset demangle state for the next round. */
2585 *mangled
= mangle_init
;
2586 string_clear (declp
);
2587 string_appends (declp
, &decl_init
);
2588 work_stuff_copy_to_from (work
, &work_init
);
2590 /* Leave this underscore-sequence. */
2593 /* Scan for the next "__" sequence. */
2594 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2597 /* Move to last "__" in this sequence. */
2598 while (*scan
&& *scan
== '_')
2603 /* Delete saved state. */
2604 delete_work_stuff (&work_init
);
2605 string_delete (&decl_init
);
2614 demangle_prefix -- consume the mangled name prefix and find signature
2619 demangle_prefix (struct work_stuff *work, const char **mangled,
2624 Consume and demangle the prefix of the mangled name.
2625 While processing the function name root, arrange to call
2626 demangle_signature if the root is ambiguous.
2628 DECLP points to the string buffer into which demangled output is
2629 placed. On entry, the buffer is empty. On exit it contains
2630 the root function name, the demangled operator name, or in some
2631 special cases either nothing or the completely demangled result.
2633 MANGLED points to the current pointer into the mangled name. As each
2634 token of the mangled name is consumed, it is updated. Upon entry
2635 the current mangled name pointer points to the first character of
2636 the mangled name. Upon exit, it should point to the first character
2637 of the signature if demangling was successful, or to the first
2638 unconsumed character if demangling of the prefix was unsuccessful.
2640 Returns 1 on success, 0 otherwise.
2644 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2651 if (strlen(*mangled
) > 6
2652 && (strncmp(*mangled
, "_imp__", 6) == 0
2653 || strncmp(*mangled
, "__imp_", 6) == 0))
2655 /* it's a symbol imported from a PE dynamic library. Check for both
2656 new style prefix _imp__ and legacy __imp_ used by older versions
2659 work
->dllimported
= 1;
2661 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2663 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2664 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2666 if ((*mangled
)[9] == 'D')
2668 /* it's a GNU global destructor to be executed at program exit */
2670 work
->destructor
= 2;
2671 if (gnu_special (work
, mangled
, declp
))
2674 else if ((*mangled
)[9] == 'I')
2676 /* it's a GNU global constructor to be executed at program init */
2678 work
->constructor
= 2;
2679 if (gnu_special (work
, mangled
, declp
))
2684 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2686 /* it's a ARM global destructor to be executed at program exit */
2688 work
->destructor
= 2;
2690 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2692 /* it's a ARM global constructor to be executed at program initial */
2694 work
->constructor
= 2;
2697 /* This block of code is a reduction in strength time optimization
2699 scan = strstr (*mangled, "__"); */
2705 scan
= strchr (scan
, '_');
2706 } while (scan
!= NULL
&& *++scan
!= '_');
2708 if (scan
!= NULL
) --scan
;
2713 /* We found a sequence of two or more '_', ensure that we start at
2714 the last pair in the sequence. */
2715 i
= strspn (scan
, "_");
2726 else if (work
-> static_type
)
2728 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2733 else if ((scan
== *mangled
)
2734 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2735 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2737 /* The ARM says nothing about the mangling of local variables.
2738 But cfront mangles local variables by prepending __<nesting_level>
2739 to them. As an extension to ARM demangling we handle this case. */
2740 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2741 && ISDIGIT ((unsigned char)scan
[2]))
2743 *mangled
= scan
+ 2;
2744 consume_count (mangled
);
2745 string_append (declp
, *mangled
);
2746 *mangled
+= strlen (*mangled
);
2751 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2752 names like __Q2_3foo3bar for nested type names. So don't accept
2753 this style of constructor for cfront demangling. A GNU
2754 style member-template constructor starts with 'H'. */
2755 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2756 work
-> constructor
+= 1;
2757 *mangled
= scan
+ 2;
2760 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2762 /* Cfront-style parameterized type. Handled later as a signature. */
2766 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2768 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2769 || (scan
[2] == 'p' && scan
[3] == 's')
2770 || (scan
[2] == 'p' && scan
[3] == 't')))
2772 /* EDG-style parameterized type. Handled later as a signature. */
2776 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2778 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2779 && (scan
[2] != 't'))
2781 /* Mangled name starts with "__". Skip over any leading '_' characters,
2782 then find the next "__" that separates the prefix from the signature.
2784 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2785 || (arm_special (mangled
, declp
) == 0))
2787 while (*scan
== '_')
2791 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2793 /* No separator (I.E. "__not_mangled"), or empty signature
2794 (I.E. "__not_mangled_either__") */
2798 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2801 else if (*(scan
+ 2) != '\0')
2803 /* Mangled name does not start with "__" but does have one somewhere
2804 in there with non empty stuff after it. Looks like a global
2805 function name. Iterate over all "__":s until the right
2807 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2811 /* Doesn't look like a mangled name */
2815 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2817 string_append (declp
, *mangled
);
2818 *mangled
+= strlen (*mangled
);
2828 gnu_special -- special handling of gnu mangled strings
2833 gnu_special (struct work_stuff *work, const char **mangled,
2839 Process some special GNU style mangling forms that don't fit
2840 the normal pattern. For example:
2842 _$_3foo (destructor for class foo)
2843 _vt$foo (foo virtual table)
2844 _vt$foo$bar (foo::bar virtual table)
2845 __vt_foo (foo virtual table, new style with thunks)
2846 _3foo$varname (static data member)
2847 _Q22rs2tu$vw (static data member)
2848 __t6vector1Zii (constructor with template)
2849 __thunk_4__$_7ostream (virtual function thunk)
2853 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2859 if ((*mangled
)[0] == '_'
2860 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2861 && (*mangled
)[2] == '_')
2863 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2865 work
-> destructor
+= 1;
2867 else if ((*mangled
)[0] == '_'
2868 && (((*mangled
)[1] == '_'
2869 && (*mangled
)[2] == 'v'
2870 && (*mangled
)[3] == 't'
2871 && (*mangled
)[4] == '_')
2872 || ((*mangled
)[1] == 'v'
2873 && (*mangled
)[2] == 't'
2874 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2876 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2877 and create the decl. Note that we consume the entire mangled
2878 input string, which means that demangle_signature has no work
2880 if ((*mangled
)[2] == 'v')
2881 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2883 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2884 while (**mangled
!= '\0')
2890 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2893 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2897 if (ISDIGIT((unsigned char)*mangled
[0]))
2899 n
= consume_count(mangled
);
2900 /* We may be seeing a too-large size, or else a
2901 ".<digits>" indicating a static local symbol. In
2902 any case, declare victory and move on; *don't* try
2903 to use n to allocate. */
2904 if (n
> (int) strlen (*mangled
))
2912 n
= strcspn (*mangled
, cplus_markers
);
2914 string_appendn (declp
, *mangled
, n
);
2918 p
= strpbrk (*mangled
, cplus_markers
);
2919 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2923 string_append (declp
, SCOPE_STRING (work
));
2934 string_append (declp
, " virtual table");
2936 else if ((*mangled
)[0] == '_'
2937 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2938 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2940 /* static data member, "_3foo$varname" for example */
2946 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2949 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2952 n
= consume_count (mangled
);
2953 if (n
< 0 || n
> (long) strlen (*mangled
))
2959 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2960 && (*mangled
)[9] == 'N'
2961 && (*mangled
)[8] == (*mangled
)[10]
2962 && strchr (cplus_markers
, (*mangled
)[8]))
2964 /* A member of the anonymous namespace. There's information
2965 about what identifier or filename it was keyed to, but
2966 it's just there to make the mangled name unique; we just
2968 string_append (declp
, "{anonymous}");
2971 /* Now p points to the marker before the N, so we need to
2972 update it to the first marker after what we consumed. */
2973 p
= strpbrk (*mangled
, cplus_markers
);
2977 string_appendn (declp
, *mangled
, n
);
2980 if (success
&& (p
== *mangled
))
2982 /* Consumed everything up to the cplus_marker, append the
2985 string_append (declp
, SCOPE_STRING (work
));
2986 n
= strlen (*mangled
);
2987 string_appendn (declp
, *mangled
, n
);
2995 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
3000 delta
= consume_count (mangled
);
3005 char *method
= internal_cplus_demangle (work
, ++*mangled
);
3010 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
3011 string_append (declp
, buf
);
3012 string_append (declp
, method
);
3014 n
= strlen (*mangled
);
3023 else if (strncmp (*mangled
, "__t", 3) == 0
3024 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
3026 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
3032 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3035 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3038 success
= do_type (work
, mangled
, declp
);
3041 if (success
&& **mangled
!= '\0')
3044 string_append (declp
, p
);
3054 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
3055 string
*result
, int namelength
)
3057 char * recurse
= (char *)NULL
;
3058 char * recurse_dem
= (char *)NULL
;
3060 recurse
= XNEWVEC (char, namelength
+ 1);
3061 memcpy (recurse
, *mangled
, namelength
);
3062 recurse
[namelength
] = '\000';
3064 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3068 string_append (result
, recurse_dem
);
3073 string_appendn (result
, *mangled
, namelength
);
3076 *mangled
+= namelength
;
3083 arm_special -- special handling of ARM/lucid mangled strings
3088 arm_special (const char **mangled,
3094 Process some special ARM style mangling forms that don't fit
3095 the normal pattern. For example:
3097 __vtbl__3foo (foo virtual table)
3098 __vtbl__3foo__3bar (bar::foo virtual table)
3103 arm_special (const char **mangled
, string
*declp
)
3109 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3111 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3112 and create the decl. Note that we consume the entire mangled
3113 input string, which means that demangle_signature has no work
3115 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3116 while (*scan
!= '\0') /* first check it can be demangled */
3118 n
= consume_count (&scan
);
3121 return (0); /* no good */
3124 if (scan
[0] == '_' && scan
[1] == '_')
3129 (*mangled
) += ARM_VTABLE_STRLEN
;
3130 while (**mangled
!= '\0')
3132 n
= consume_count (mangled
);
3134 || n
> (long) strlen (*mangled
))
3136 string_prependn (declp
, *mangled
, n
);
3138 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3140 string_prepend (declp
, "::");
3144 string_append (declp
, " virtual table");
3157 demangle_qualified -- demangle 'Q' qualified name strings
3162 demangle_qualified (struct work_stuff *, const char *mangled,
3163 string *result, int isfuncname, int append);
3167 Demangle a qualified name, such as "Q25Outer5Inner" which is
3168 the mangled form of "Outer::Inner". The demangled output is
3169 prepended or appended to the result string according to the
3170 state of the append flag.
3172 If isfuncname is nonzero, then the qualified name we are building
3173 is going to be used as a member function name, so if it is a
3174 constructor or destructor function, append an appropriate
3175 constructor or destructor name. I.E. for the above example,
3176 the result for use as a constructor is "Outer::Inner::Inner"
3177 and the result for use as a destructor is "Outer::Inner::~Inner".
3181 Numeric conversion is ASCII dependent (FIXME).
3186 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3187 string
*result
, int isfuncname
, int append
)
3194 int bindex
= register_Btype (work
);
3196 /* We only make use of ISFUNCNAME if the entity is a constructor or
3198 isfuncname
= (isfuncname
3199 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3201 string_init (&temp
);
3202 string_init (&last_name
);
3204 if ((*mangled
)[0] == 'K')
3206 /* Squangling qualified name reuse */
3209 idx
= consume_count_with_underscores (mangled
);
3210 if (idx
== -1 || idx
>= work
-> numk
)
3213 string_append (&temp
, work
-> ktypevec
[idx
]);
3216 switch ((*mangled
)[1])
3219 /* GNU mangled name with more than 9 classes. The count is preceded
3220 by an underscore (to distinguish it from the <= 9 case) and followed
3221 by an underscore. */
3223 qualifiers
= consume_count_with_underscores (mangled
);
3224 if (qualifiers
== -1)
3237 /* The count is in a single digit. */
3238 num
[0] = (*mangled
)[1];
3240 qualifiers
= atoi (num
);
3242 /* If there is an underscore after the digit, skip it. This is
3243 said to be for ARM-qualified names, but the ARM makes no
3244 mention of such an underscore. Perhaps cfront uses one. */
3245 if ((*mangled
)[2] == '_')
3260 /* Pick off the names and collect them in the temp buffer in the order
3261 in which they are found, separated by '::'. */
3263 while (qualifiers
-- > 0)
3266 string_clear (&last_name
);
3268 if (*mangled
[0] == '_')
3271 if (*mangled
[0] == 't')
3273 /* Here we always append to TEMP since we will want to use
3274 the template name without the template parameters as a
3275 constructor or destructor name. The appropriate
3276 (parameter-less) value is returned by demangle_template
3277 in LAST_NAME. We do not remember the template type here,
3278 in order to match the G++ mangling algorithm. */
3279 success
= demangle_template(work
, mangled
, &temp
,
3284 else if (*mangled
[0] == 'K')
3288 idx
= consume_count_with_underscores (mangled
);
3289 if (idx
== -1 || idx
>= work
->numk
)
3292 string_append (&temp
, work
->ktypevec
[idx
]);
3295 if (!success
) break;
3302 /* Now recursively demangle the qualifier
3303 * This is necessary to deal with templates in
3304 * mangling styles like EDG */
3305 namelength
= consume_count (mangled
);
3306 if (namelength
== -1)
3311 recursively_demangle(work
, mangled
, &temp
, namelength
);
3315 string_delete (&last_name
);
3316 success
= do_type (work
, mangled
, &last_name
);
3319 string_appends (&temp
, &last_name
);
3324 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3327 string_append (&temp
, SCOPE_STRING (work
));
3330 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3332 /* If we are using the result as a function name, we need to append
3333 the appropriate '::' separated constructor or destructor name.
3334 We do this here because this is the most convenient place, where
3335 we already have a pointer to the name and the length of the name. */
3339 string_append (&temp
, SCOPE_STRING (work
));
3340 if (work
-> destructor
& 1)
3341 string_append (&temp
, "~");
3342 string_appends (&temp
, &last_name
);
3345 /* Now either prepend the temp buffer to the result, or append it,
3346 depending upon the state of the append flag. */
3349 string_appends (result
, &temp
);
3352 if (!STRING_EMPTY (result
))
3353 string_append (&temp
, SCOPE_STRING (work
));
3354 string_prepends (result
, &temp
);
3357 string_delete (&last_name
);
3358 string_delete (&temp
);
3366 get_count -- convert an ascii count to integer, consuming tokens
3371 get_count (const char **type, int *count)
3375 Assume that *type points at a count in a mangled name; set
3376 *count to its value, and set *type to the next character after
3377 the count. There are some weird rules in effect here.
3379 If *type does not point at a string of digits, return zero.
3381 If *type points at a string of digits followed by an
3382 underscore, set *count to their value as an integer, advance
3383 *type to point *after the underscore, and return 1.
3385 If *type points at a string of digits not followed by an
3386 underscore, consume only the first digit. Set *count to its
3387 value as an integer, leave *type pointing after that digit,
3390 The excuse for this odd behavior: in the ARM and HP demangling
3391 styles, a type can be followed by a repeat count of the form
3394 `x' is a single digit specifying how many additional copies
3395 of the type to append to the argument list, and
3397 `y' is one or more digits, specifying the zero-based index of
3398 the first repeated argument in the list. Yes, as you're
3399 unmangling the name you can figure this out yourself, but
3402 So, for example, in `bar__3fooFPiN51', the first argument is a
3403 pointer to an integer (`Pi'), and then the next five arguments
3404 are the same (`N5'), and the first repeat is the function's
3405 second argument (`1').
3409 get_count (const char **type
, int *count
)
3414 if (!ISDIGIT ((unsigned char)**type
))
3418 *count
= **type
- '0';
3420 if (ISDIGIT ((unsigned char)**type
))
3430 while (ISDIGIT ((unsigned char)*p
));
3441 /* RESULT will be initialised here; it will be freed on failure. The
3442 value returned is really a type_kind_t. */
3445 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3451 const char *remembered_type
;
3453 type_kind_t tk
= tk_none
;
3455 string_init (&decl
);
3456 string_init (result
);
3460 while (success
&& !done
)
3466 /* A pointer type */
3470 if (! (work
-> options
& DMGL_JAVA
))
3471 string_prepend (&decl
, "*");
3476 /* A reference type */
3479 string_prepend (&decl
, "&");
3488 if (!STRING_EMPTY (&decl
)
3489 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3491 string_prepend (&decl
, "(");
3492 string_append (&decl
, ")");
3494 string_append (&decl
, "[");
3495 if (**mangled
!= '_')
3496 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3498 if (**mangled
== '_')
3500 string_append (&decl
, "]");
3504 /* A back reference to a previously seen type */
3507 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3513 remembered_type
= work
-> typevec
[n
];
3514 mangled
= &remembered_type
;
3521 if (!STRING_EMPTY (&decl
)
3522 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3524 string_prepend (&decl
, "(");
3525 string_append (&decl
, ")");
3527 /* After picking off the function args, we expect to either find the
3528 function return type (preceded by an '_') or the end of the
3530 if (!demangle_nested_args (work
, mangled
, &decl
)
3531 || (**mangled
!= '_' && **mangled
!= '\0'))
3536 if (success
&& (**mangled
== '_'))
3543 type_quals
= TYPE_UNQUALIFIED
;
3545 member
= **mangled
== 'M';
3548 string_append (&decl
, ")");
3550 /* We don't need to prepend `::' for a qualified name;
3551 demangle_qualified will do that for us. */
3552 if (**mangled
!= 'Q')
3553 string_prepend (&decl
, SCOPE_STRING (work
));
3555 if (ISDIGIT ((unsigned char)**mangled
))
3557 n
= consume_count (mangled
);
3559 || (int) strlen (*mangled
) < n
)
3564 string_prependn (&decl
, *mangled
, n
);
3567 else if (**mangled
== 'X' || **mangled
== 'Y')
3570 do_type (work
, mangled
, &temp
);
3571 string_prepends (&decl
, &temp
);
3572 string_delete (&temp
);
3574 else if (**mangled
== 't')
3577 string_init (&temp
);
3578 success
= demangle_template (work
, mangled
, &temp
,
3582 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3583 string_delete (&temp
);
3588 else if (**mangled
== 'Q')
3590 success
= demangle_qualified (work
, mangled
, &decl
,
3602 string_prepend (&decl
, "(");
3610 type_quals
|= code_for_qualifier (**mangled
);
3618 if (*(*mangled
)++ != 'F')
3624 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3625 || **mangled
!= '_')
3631 if (! PRINT_ANSI_QUALIFIERS
)
3635 if (type_quals
!= TYPE_UNQUALIFIED
)
3637 APPEND_BLANK (&decl
);
3638 string_append (&decl
, qualifier_string (type_quals
));
3649 if (PRINT_ANSI_QUALIFIERS
)
3651 if (!STRING_EMPTY (&decl
))
3652 string_prepend (&decl
, " ");
3654 string_prepend (&decl
, demangle_qualifier (**mangled
));
3669 if (success
) switch (**mangled
)
3671 /* A qualified name, such as "Outer::Inner". */
3675 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3679 /* A back reference to a previously seen squangled type */
3682 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3685 string_append (result
, work
->btypevec
[n
]);
3690 /* A template parm. We substitute the corresponding argument. */
3695 idx
= consume_count_with_underscores (mangled
);
3698 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3699 || consume_count_with_underscores (mangled
) == -1)
3705 if (work
->tmpl_argvec
)
3706 string_append (result
, work
->tmpl_argvec
[idx
]);
3708 string_append_template_idx (result
, idx
);
3715 success
= demangle_fund_type (work
, mangled
, result
);
3717 tk
= (type_kind_t
) success
;
3723 if (!STRING_EMPTY (&decl
))
3725 string_append (result
, " ");
3726 string_appends (result
, &decl
);
3730 string_delete (result
);
3731 string_delete (&decl
);
3734 /* Assume an integral type, if we're not sure. */
3735 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3740 /* Given a pointer to a type string that represents a fundamental type
3741 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3742 string in which the demangled output is being built in RESULT, and
3743 the WORK structure, decode the types and add them to the result.
3748 "Sl" => "signed long"
3749 "CUs" => "const unsigned short"
3751 The value returned is really a type_kind_t. */
3754 demangle_fund_type (struct work_stuff
*work
,
3755 const char **mangled
, string
*result
)
3759 char buf
[INTBUF_SIZE
+ 5 /* 'int%u_t' */];
3760 unsigned int dec
= 0;
3761 type_kind_t tk
= tk_integral
;
3763 /* First pick off any type qualifiers. There can be more than one. */
3772 if (PRINT_ANSI_QUALIFIERS
)
3774 if (!STRING_EMPTY (result
))
3775 string_prepend (result
, " ");
3776 string_prepend (result
, demangle_qualifier (**mangled
));
3782 APPEND_BLANK (result
);
3783 string_append (result
, "unsigned");
3785 case 'S': /* signed char only */
3787 APPEND_BLANK (result
);
3788 string_append (result
, "signed");
3792 APPEND_BLANK (result
);
3793 string_append (result
, "__complex");
3801 /* Now pick off the fundamental type. There can be only one. */
3810 APPEND_BLANK (result
);
3811 string_append (result
, "void");
3815 APPEND_BLANK (result
);
3816 string_append (result
, "long long");
3820 APPEND_BLANK (result
);
3821 string_append (result
, "long");
3825 APPEND_BLANK (result
);
3826 string_append (result
, "int");
3830 APPEND_BLANK (result
);
3831 string_append (result
, "short");
3835 APPEND_BLANK (result
);
3836 string_append (result
, "bool");
3841 APPEND_BLANK (result
);
3842 string_append (result
, "char");
3847 APPEND_BLANK (result
);
3848 string_append (result
, "wchar_t");
3853 APPEND_BLANK (result
);
3854 string_append (result
, "long double");
3859 APPEND_BLANK (result
);
3860 string_append (result
, "double");
3865 APPEND_BLANK (result
);
3866 string_append (result
, "float");
3871 if (!ISDIGIT ((unsigned char)**mangled
))
3878 if (**mangled
== '_')
3883 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3886 if (**mangled
!= '_')
3896 strncpy (buf
, *mangled
, 2);
3898 *mangled
+= min (strlen (*mangled
), 2);
3900 sscanf (buf
, "%x", &dec
);
3901 sprintf (buf
, "int%u_t", dec
);
3902 APPEND_BLANK (result
);
3903 string_append (result
, buf
);
3907 /* An explicit type, such as "6mytype" or "7integer" */
3919 int bindex
= register_Btype (work
);
3921 string_init (&btype
);
3922 if (demangle_class_name (work
, mangled
, &btype
)) {
3923 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3924 APPEND_BLANK (result
);
3925 string_appends (result
, &btype
);
3929 string_delete (&btype
);
3935 string_init (&btype
);
3936 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3937 string_appends (result
, &btype
);
3938 string_delete (&btype
);
3946 return success
? ((int) tk
) : 0;
3950 /* Handle a template's value parameter for HP aCC (extension from ARM)
3951 **mangled points to 'S' or 'U' */
3954 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
3955 const char **mangled
, string
*result
)
3959 if (**mangled
!= 'U' && **mangled
!= 'S')
3962 unsigned_const
= (**mangled
== 'U');
3969 string_append (result
, "-");
3975 /* special case for -2^31 */
3976 string_append (result
, "-2147483648");
3983 /* We have to be looking at an integer now */
3984 if (!(ISDIGIT ((unsigned char)**mangled
)))
3987 /* We only deal with integral values for template
3988 parameters -- so it's OK to look only for digits */
3989 while (ISDIGIT ((unsigned char)**mangled
))
3991 char_str
[0] = **mangled
;
3992 string_append (result
, char_str
);
3997 string_append (result
, "U");
3999 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4000 with L or LL suffixes. pai/1997-09-03 */
4002 return 1; /* success */
4005 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4006 **mangled is pointing to the 'A' */
4009 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
4012 int literal_len
= 0;
4016 if (**mangled
!= 'A')
4021 literal_len
= consume_count (mangled
);
4023 if (literal_len
<= 0)
4026 /* Literal parameters are names of arrays, functions, etc. and the
4027 canonical representation uses the address operator */
4028 string_append (result
, "&");
4030 /* Now recursively demangle the literal name */
4031 recurse
= XNEWVEC (char, literal_len
+ 1);
4032 memcpy (recurse
, *mangled
, literal_len
);
4033 recurse
[literal_len
] = '\000';
4035 recurse_dem
= cplus_demangle (recurse
, work
->options
);
4039 string_append (result
, recurse_dem
);
4044 string_appendn (result
, *mangled
, literal_len
);
4046 (*mangled
) += literal_len
;
4053 snarf_numeric_literal (const char **args
, string
*arg
)
4058 string_append (arg
, char_str
);
4061 else if (**args
== '+')
4064 if (!ISDIGIT ((unsigned char)**args
))
4067 while (ISDIGIT ((unsigned char)**args
))
4069 char_str
[0] = **args
;
4070 string_append (arg
, char_str
);
4077 /* Demangle the next argument, given by MANGLED into RESULT, which
4078 *should be an uninitialized* string. It will be initialized here,
4079 and free'd should anything go wrong. */
4082 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4084 /* Remember where we started so that we can record the type, for
4085 non-squangling type remembering. */
4086 const char *start
= *mangled
;
4088 string_init (result
);
4090 if (work
->nrepeats
> 0)
4094 if (work
->previous_argument
== 0)
4097 /* We want to reissue the previous type in this argument list. */
4098 string_appends (result
, work
->previous_argument
);
4102 if (**mangled
== 'n')
4104 /* A squangling-style repeat. */
4106 work
->nrepeats
= consume_count(mangled
);
4108 if (work
->nrepeats
<= 0)
4109 /* This was not a repeat count after all. */
4112 if (work
->nrepeats
> 9)
4114 if (**mangled
!= '_')
4115 /* The repeat count should be followed by an '_' in this
4122 /* Now, the repeat is all set up. */
4123 return do_arg (work
, mangled
, result
);
4126 /* Save the result in WORK->previous_argument so that we can find it
4127 if it's repeated. Note that saving START is not good enough: we
4128 do not want to add additional types to the back-referenceable
4129 type vector when processing a repeated type. */
4130 if (work
->previous_argument
)
4131 string_delete (work
->previous_argument
);
4133 work
->previous_argument
= XNEW (string
);
4135 if (!do_type (work
, mangled
, work
->previous_argument
))
4138 string_appends (result
, work
->previous_argument
);
4140 remember_type (work
, start
, *mangled
- start
);
4145 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4149 if (work
->forgetting_types
)
4152 if (work
-> ntypes
>= work
-> typevec_size
)
4154 if (work
-> typevec_size
== 0)
4156 work
-> typevec_size
= 3;
4157 work
-> typevec
= XNEWVEC (char *, work
->typevec_size
);
4161 work
-> typevec_size
*= 2;
4163 = XRESIZEVEC (char *, work
->typevec
, work
->typevec_size
);
4166 tem
= XNEWVEC (char, len
+ 1);
4167 memcpy (tem
, start
, len
);
4169 work
-> typevec
[work
-> ntypes
++] = tem
;
4173 /* Remember a K type class qualifier. */
4175 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4179 if (work
-> numk
>= work
-> ksize
)
4181 if (work
-> ksize
== 0)
4184 work
-> ktypevec
= XNEWVEC (char *, work
->ksize
);
4190 = XRESIZEVEC (char *, work
->ktypevec
, work
->ksize
);
4193 tem
= XNEWVEC (char, len
+ 1);
4194 memcpy (tem
, start
, len
);
4196 work
-> ktypevec
[work
-> numk
++] = tem
;
4199 /* Register a B code, and get an index for it. B codes are registered
4200 as they are seen, rather than as they are completed, so map<temp<char> >
4201 registers map<temp<char> > as B0, and temp<char> as B1 */
4204 register_Btype (struct work_stuff
*work
)
4208 if (work
-> numb
>= work
-> bsize
)
4210 if (work
-> bsize
== 0)
4213 work
-> btypevec
= XNEWVEC (char *, work
->bsize
);
4219 = XRESIZEVEC (char *, work
->btypevec
, work
->bsize
);
4222 ret
= work
-> numb
++;
4223 work
-> btypevec
[ret
] = NULL
;
4227 /* Store a value into a previously registered B code type. */
4230 remember_Btype (struct work_stuff
*work
, const char *start
,
4235 tem
= XNEWVEC (char, len
+ 1);
4236 memcpy (tem
, start
, len
);
4238 work
-> btypevec
[index
] = tem
;
4241 /* Lose all the info related to B and K type codes. */
4243 forget_B_and_K_types (struct work_stuff
*work
)
4247 while (work
-> numk
> 0)
4249 i
= --(work
-> numk
);
4250 if (work
-> ktypevec
[i
] != NULL
)
4252 free (work
-> ktypevec
[i
]);
4253 work
-> ktypevec
[i
] = NULL
;
4257 while (work
-> numb
> 0)
4259 i
= --(work
-> numb
);
4260 if (work
-> btypevec
[i
] != NULL
)
4262 free (work
-> btypevec
[i
]);
4263 work
-> btypevec
[i
] = NULL
;
4267 /* Forget the remembered types, but not the type vector itself. */
4270 forget_types (struct work_stuff
*work
)
4274 while (work
-> ntypes
> 0)
4276 i
= --(work
-> ntypes
);
4277 if (work
-> typevec
[i
] != NULL
)
4279 free (work
-> typevec
[i
]);
4280 work
-> typevec
[i
] = NULL
;
4285 /* Process the argument list part of the signature, after any class spec
4286 has been consumed, as well as the first 'F' character (if any). For
4289 "__als__3fooRT0" => process "RT0"
4290 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4292 DECLP must be already initialised, usually non-empty. It won't be freed
4295 Note that g++ differs significantly from ARM and lucid style mangling
4296 with regards to references to previously seen types. For example, given
4297 the source fragment:
4301 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4304 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4305 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4307 g++ produces the names:
4312 while lcc (and presumably other ARM style compilers as well) produces:
4314 foo__FiR3fooT1T2T1T2
4315 __ct__3fooFiR3fooT1T2T1T2
4317 Note that g++ bases its type numbers starting at zero and counts all
4318 previously seen types, while lucid/ARM bases its type numbers starting
4319 at one and only considers types after it has seen the 'F' character
4320 indicating the start of the function args. For lucid/ARM style, we
4321 account for this difference by discarding any previously seen types when
4322 we see the 'F' character, and subtracting one from the type number
4328 demangle_args (struct work_stuff
*work
, const char **mangled
,
4338 if (PRINT_ARG_TYPES
)
4340 string_append (declp
, "(");
4341 if (**mangled
== '\0')
4343 string_append (declp
, "void");
4347 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4348 || work
->nrepeats
> 0)
4350 if ((**mangled
== 'N') || (**mangled
== 'T'))
4352 temptype
= *(*mangled
)++;
4354 if (temptype
== 'N')
4356 if (!get_count (mangled
, &r
))
4365 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4367 /* If we have 10 or more types we might have more than a 1 digit
4368 index so we'll have to consume the whole count here. This
4369 will lose if the next thing is a type name preceded by a
4370 count but it's impossible to demangle that case properly
4371 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4372 Pc, ...)" or "(..., type12, char *, ...)" */
4373 if ((t
= consume_count(mangled
)) <= 0)
4380 if (!get_count (mangled
, &t
))
4385 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4389 /* Validate the type index. Protect against illegal indices from
4390 malformed type strings. */
4391 if ((t
< 0) || (t
>= work
-> ntypes
))
4395 while (work
->nrepeats
> 0 || --r
>= 0)
4397 tem
= work
-> typevec
[t
];
4398 if (need_comma
&& PRINT_ARG_TYPES
)
4400 string_append (declp
, ", ");
4402 if (!do_arg (work
, &tem
, &arg
))
4406 if (PRINT_ARG_TYPES
)
4408 string_appends (declp
, &arg
);
4410 string_delete (&arg
);
4416 if (need_comma
&& PRINT_ARG_TYPES
)
4417 string_append (declp
, ", ");
4418 if (!do_arg (work
, mangled
, &arg
))
4420 if (PRINT_ARG_TYPES
)
4421 string_appends (declp
, &arg
);
4422 string_delete (&arg
);
4427 if (**mangled
== 'e')
4430 if (PRINT_ARG_TYPES
)
4434 string_append (declp
, ",");
4436 string_append (declp
, "...");
4440 if (PRINT_ARG_TYPES
)
4442 string_append (declp
, ")");
4447 /* Like demangle_args, but for demangling the argument lists of function
4448 and method pointers or references, not top-level declarations. */
4451 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4454 string
* saved_previous_argument
;
4458 /* The G++ name-mangling algorithm does not remember types on nested
4459 argument lists, unless -fsquangling is used, and in that case the
4460 type vector updated by remember_type is not used. So, we turn
4461 off remembering of types here. */
4462 ++work
->forgetting_types
;
4464 /* For the repeat codes used with -fsquangling, we must keep track of
4465 the last argument. */
4466 saved_previous_argument
= work
->previous_argument
;
4467 saved_nrepeats
= work
->nrepeats
;
4468 work
->previous_argument
= 0;
4471 /* Actually demangle the arguments. */
4472 result
= demangle_args (work
, mangled
, declp
);
4474 /* Restore the previous_argument field. */
4475 if (work
->previous_argument
)
4477 string_delete (work
->previous_argument
);
4478 free ((char *) work
->previous_argument
);
4480 work
->previous_argument
= saved_previous_argument
;
4481 --work
->forgetting_types
;
4482 work
->nrepeats
= saved_nrepeats
;
4487 /* Returns 1 if a valid function name was found or 0 otherwise. */
4490 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4491 string
*declp
, const char *scan
)
4497 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4498 string_need (declp
, 1);
4499 *(declp
-> p
) = '\0';
4501 /* Consume the function name, including the "__" separating the name
4502 from the signature. We are guaranteed that SCAN points to the
4505 (*mangled
) = scan
+ 2;
4506 /* We may be looking at an instantiation of a template function:
4507 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4508 following _F marks the start of the function arguments. Handle
4509 the template arguments first. */
4511 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4513 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4514 /* This leaves MANGLED pointing to the 'F' marking func args */
4517 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4520 /* See if we have an ARM style constructor or destructor operator.
4521 If so, then just record it, clear the decl, and return.
4522 We can't build the actual constructor/destructor decl until later,
4523 when we recover the class name from the signature. */
4525 if (strcmp (declp
-> b
, "__ct") == 0)
4527 work
-> constructor
+= 1;
4528 string_clear (declp
);
4531 else if (strcmp (declp
-> b
, "__dt") == 0)
4533 work
-> destructor
+= 1;
4534 string_clear (declp
);
4539 if (declp
->p
- declp
->b
>= 3
4540 && declp
->b
[0] == 'o'
4541 && declp
->b
[1] == 'p'
4542 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4544 /* see if it's an assignment expression */
4545 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4546 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4548 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4550 int len
= declp
->p
- declp
->b
- 10;
4551 if ((int) strlen (optable
[i
].in
) == len
4552 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4554 string_clear (declp
);
4555 string_append (declp
, "operator");
4556 string_append (declp
, optable
[i
].out
);
4557 string_append (declp
, "=");
4564 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4566 int len
= declp
->p
- declp
->b
- 3;
4567 if ((int) strlen (optable
[i
].in
) == len
4568 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4570 string_clear (declp
);
4571 string_append (declp
, "operator");
4572 string_append (declp
, optable
[i
].out
);
4578 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4579 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4581 /* type conversion operator */
4583 if (do_type (work
, &tem
, &type
))
4585 string_clear (declp
);
4586 string_append (declp
, "operator ");
4587 string_appends (declp
, &type
);
4588 string_delete (&type
);
4591 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4592 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4595 /* type conversion operator. */
4597 if (do_type (work
, &tem
, &type
))
4599 string_clear (declp
);
4600 string_append (declp
, "operator ");
4601 string_appends (declp
, &type
);
4602 string_delete (&type
);
4605 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4606 && ISLOWER((unsigned char)declp
->b
[2])
4607 && ISLOWER((unsigned char)declp
->b
[3]))
4609 if (declp
->b
[4] == '\0')
4612 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4614 if (strlen (optable
[i
].in
) == 2
4615 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4617 string_clear (declp
);
4618 string_append (declp
, "operator");
4619 string_append (declp
, optable
[i
].out
);
4626 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4629 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4631 if (strlen (optable
[i
].in
) == 3
4632 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4634 string_clear (declp
);
4635 string_append (declp
, "operator");
4636 string_append (declp
, optable
[i
].out
);
4644 /* If a function name was obtained but it's not valid, we were not
4646 if (LEN_STRING (declp
) == 1 && declp
->b
[0] == '.')
4652 /* a mini string-handling package */
4655 string_need (string
*s
, int n
)
4665 s
->p
= s
->b
= XNEWVEC (char, n
);
4668 else if (s
->e
- s
->p
< n
)
4673 s
->b
= XRESIZEVEC (char, s
->b
, n
);
4680 string_delete (string
*s
)
4685 s
->b
= s
->e
= s
->p
= NULL
;
4690 string_init (string
*s
)
4692 s
->b
= s
->p
= s
->e
= NULL
;
4696 string_clear (string
*s
)
4704 string_empty (string
*s
)
4706 return (s
->b
== s
->p
);
4712 string_append (string
*p
, const char *s
)
4715 if (s
== NULL
|| *s
== '\0')
4719 memcpy (p
->p
, s
, n
);
4724 string_appends (string
*p
, string
*s
)
4732 memcpy (p
->p
, s
->b
, n
);
4738 string_appendn (string
*p
, const char *s
, int n
)
4743 memcpy (p
->p
, s
, n
);
4749 string_prepend (string
*p
, const char *s
)
4751 if (s
!= NULL
&& *s
!= '\0')
4753 string_prependn (p
, s
, strlen (s
));
4758 string_prepends (string
*p
, string
*s
)
4762 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4767 string_prependn (string
*p
, const char *s
, int n
)
4774 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4778 memcpy (p
->b
, s
, n
);
4784 string_append_template_idx (string
*s
, int idx
)
4786 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4787 sprintf(buf
, "T%d", idx
);
4788 string_append (s
, buf
);