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.
899 A few special names such as '___elabs' add a few chars (at most 7), but
900 they occur only once. */
901 len0
= strlen (mangled
) + 7 + 1;
902 demangled
= XNEWVEC (char, len0
);
908 /* An entity names is expected. */
911 /* An identifier, which is always lower case. */
914 while (ISLOWER(*p
) || ISDIGIT (*p
)
915 || (p
[0] == '_' && (ISLOWER (p
[1]) || ISDIGIT (p
[1]))));
917 else if (p
[0] == 'O')
919 /* An operator name. */
920 static const char * const operators
[][2] =
921 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
922 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
923 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
924 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
925 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
926 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
927 {"Oexpon", "**"}, {NULL
, NULL
}};
930 for (k
= 0; operators
[k
][0] != NULL
; k
++)
932 size_t slen
= strlen (operators
[k
][0]);
933 if (strncmp (p
, operators
[k
][0], slen
) == 0)
936 slen
= strlen (operators
[k
][1]);
938 memcpy (d
, operators
[k
][1], slen
);
944 /* Operator not found. */
945 if (operators
[k
][0] == NULL
)
950 /* Not a GNAT encoding. */
954 /* The name can be directly followed by some uppercase letters. */
955 if (p
[0] == 'T' && p
[1] == 'K')
958 if (p
[2] == 'B' && p
[3] == 0)
960 /* Subprogram for task body. */
963 else if (p
[2] == '_' && p
[3] == '_')
965 /* Inner declarations in a task. */
973 if (p
[0] == 'E' && p
[1] == 0)
975 /* Exception name. */
978 if ((p
[0] == 'P' || p
[0] == 'N') && p
[1] == 0)
980 /* Protected type subprogram. */
983 if ((*p
== 'N' || *p
== 'S') && p
[1] == 0)
985 /* Enumerated type name table. */
992 while (p
[0] == 'n' || p
[0] == 'b')
995 if (p
[0] == 'S' && p
[1] != 0 && (p
[2] == '_' || p
[2] == 0))
997 /* Stream operations. */
1020 else if (p
[0] == 'D')
1022 /* Controlled type operation. */
1045 /* Standard separator. Handled first. */
1050 /* Overloading number. */
1053 while (ISDIGIT (*p
) || (p
[0] == '_' && ISDIGIT (p
[1])));
1057 while (p
[0] == 'n' || p
[0] == 'b')
1061 else if (p
[0] == '_' && p
[1] != '_')
1063 /* Special names. */
1064 static const char * const special
[][2] = {
1065 { "_elabb", "'Elab_Body" },
1066 { "_elabs", "'Elab_Spec" },
1067 { "_size", "'Size" },
1068 { "_alignment", "'Alignment" },
1069 { "_assign", ".\":=\"" },
1074 for (k
= 0; special
[k
][0] != NULL
; k
++)
1076 size_t slen
= strlen (special
[k
][0]);
1077 if (strncmp (p
, special
[k
][0], slen
) == 0)
1080 slen
= strlen (special
[k
][1]);
1081 memcpy (d
, special
[k
][1], slen
);
1086 if (special
[k
][0] != NULL
)
1097 else if (p
[1] == 'B' || p
[1] == 'E')
1099 /* Entry Body or barrier Evaluation. */
1101 while (ISDIGIT (*p
))
1103 if (p
[0] == 's' && p
[1] == 0)
1112 if (p
[0] == '.' && ISDIGIT (p
[1]))
1114 /* Nested subprogram. */
1116 while (ISDIGIT (*p
))
1121 /* End of mangled name. */
1131 len0
= strlen (mangled
);
1132 demangled
= XNEWVEC (char, len0
+ 3);
1134 if (mangled
[0] == '<')
1135 strcpy (demangled
, mangled
);
1137 sprintf (demangled
, "<%s>", mangled
);
1142 /* This function performs most of what cplus_demangle use to do, but
1143 to be able to demangle a name with a B, K or n code, we need to
1144 have a longer term memory of what types have been seen. The original
1145 now initializes and cleans up the squangle code info, while internal
1146 calls go directly to this routine to avoid resetting that info. */
1149 internal_cplus_demangle (struct work_stuff
*work
, const char *mangled
)
1154 char *demangled
= NULL
;
1156 s1
= work
->constructor
;
1157 s2
= work
->destructor
;
1158 s3
= work
->static_type
;
1159 s4
= work
->type_quals
;
1160 work
->constructor
= work
->destructor
= 0;
1161 work
->type_quals
= TYPE_UNQUALIFIED
;
1162 work
->dllimported
= 0;
1164 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
1166 string_init (&decl
);
1168 /* First check to see if gnu style demangling is active and if the
1169 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1170 recognize one of the gnu special forms rather than looking for a
1171 standard prefix. In particular, don't worry about whether there
1172 is a "__" string in the mangled string. Consider "_$_5__foo" for
1175 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
1177 success
= gnu_special (work
, &mangled
, &decl
);
1181 success
= demangle_prefix (work
, &mangled
, &decl
);
1183 if (success
&& (*mangled
!= '\0'))
1185 success
= demangle_signature (work
, &mangled
, &decl
);
1187 if (work
->constructor
== 2)
1189 string_prepend (&decl
, "global constructors keyed to ");
1190 work
->constructor
= 0;
1192 else if (work
->destructor
== 2)
1194 string_prepend (&decl
, "global destructors keyed to ");
1195 work
->destructor
= 0;
1197 else if (work
->dllimported
== 1)
1199 string_prepend (&decl
, "import stub for ");
1200 work
->dllimported
= 0;
1202 demangled
= mop_up (work
, &decl
, success
);
1204 work
->constructor
= s1
;
1205 work
->destructor
= s2
;
1206 work
->static_type
= s3
;
1207 work
->type_quals
= s4
;
1212 /* Clear out and squangling related storage */
1214 squangle_mop_up (struct work_stuff
*work
)
1216 /* clean up the B and K type mangling types. */
1217 forget_B_and_K_types (work
);
1218 if (work
-> btypevec
!= NULL
)
1220 free ((char *) work
-> btypevec
);
1222 if (work
-> ktypevec
!= NULL
)
1224 free ((char *) work
-> ktypevec
);
1229 /* Copy the work state and storage. */
1232 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1236 delete_work_stuff (to
);
1238 /* Shallow-copy scalars. */
1239 memcpy (to
, from
, sizeof (*to
));
1241 /* Deep-copy dynamic storage. */
1242 if (from
->typevec_size
)
1243 to
->typevec
= XNEWVEC (char *, from
->typevec_size
);
1245 for (i
= 0; i
< from
->ntypes
; i
++)
1247 int len
= strlen (from
->typevec
[i
]) + 1;
1249 to
->typevec
[i
] = XNEWVEC (char, len
);
1250 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1254 to
->ktypevec
= XNEWVEC (char *, from
->ksize
);
1256 for (i
= 0; i
< from
->numk
; i
++)
1258 int len
= strlen (from
->ktypevec
[i
]) + 1;
1260 to
->ktypevec
[i
] = XNEWVEC (char, len
);
1261 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1265 to
->btypevec
= XNEWVEC (char *, from
->bsize
);
1267 for (i
= 0; i
< from
->numb
; i
++)
1269 int len
= strlen (from
->btypevec
[i
]) + 1;
1271 to
->btypevec
[i
] = XNEWVEC (char , len
);
1272 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1275 if (from
->ntmpl_args
)
1276 to
->tmpl_argvec
= XNEWVEC (char *, from
->ntmpl_args
);
1278 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1280 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1282 to
->tmpl_argvec
[i
] = XNEWVEC (char, len
);
1283 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1286 if (from
->previous_argument
)
1288 to
->previous_argument
= XNEW (string
);
1289 string_init (to
->previous_argument
);
1290 string_appends (to
->previous_argument
, from
->previous_argument
);
1295 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1298 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1300 /* Discard the remembered types, if any. */
1302 forget_types (work
);
1303 if (work
-> typevec
!= NULL
)
1305 free ((char *) work
-> typevec
);
1306 work
-> typevec
= NULL
;
1307 work
-> typevec_size
= 0;
1309 if (work
->tmpl_argvec
)
1313 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1314 if (work
->tmpl_argvec
[i
])
1315 free ((char*) work
->tmpl_argvec
[i
]);
1317 free ((char*) work
->tmpl_argvec
);
1318 work
->tmpl_argvec
= NULL
;
1320 if (work
->previous_argument
)
1322 string_delete (work
->previous_argument
);
1323 free ((char*) work
->previous_argument
);
1324 work
->previous_argument
= NULL
;
1329 /* Delete all dynamic storage in work_stuff. */
1331 delete_work_stuff (struct work_stuff
*work
)
1333 delete_non_B_K_work_stuff (work
);
1334 squangle_mop_up (work
);
1338 /* Clear out any mangled storage */
1341 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1343 char *demangled
= NULL
;
1345 delete_non_B_K_work_stuff (work
);
1347 /* If demangling was successful, ensure that the demangled string is null
1348 terminated and return it. Otherwise, free the demangling decl. */
1352 string_delete (declp
);
1356 string_appendn (declp
, "", 1);
1357 demangled
= declp
->b
;
1366 demangle_signature -- demangle the signature part of a mangled name
1371 demangle_signature (struct work_stuff *work, const char **mangled,
1376 Consume and demangle the signature portion of the mangled name.
1378 DECLP is the string where demangled output is being built. At
1379 entry it contains the demangled root name from the mangled name
1380 prefix. I.E. either a demangled operator name or the root function
1381 name. In some special cases, it may contain nothing.
1383 *MANGLED points to the current unconsumed location in the mangled
1384 name. As tokens are consumed and demangling is performed, the
1385 pointer is updated to continuously point at the next token to
1388 Demangling GNU style mangled names is nasty because there is no
1389 explicit token that marks the start of the outermost function
1393 demangle_signature (struct work_stuff
*work
,
1394 const char **mangled
, string
*declp
)
1398 int expect_func
= 0;
1399 int expect_return_type
= 0;
1400 const char *oldmangled
= NULL
;
1404 while (success
&& (**mangled
!= '\0'))
1409 oldmangled
= *mangled
;
1410 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1412 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1413 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1419 oldmangled
= *mangled
;
1420 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1421 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1429 /* Static member function */
1430 if (oldmangled
== NULL
)
1432 oldmangled
= *mangled
;
1435 work
-> static_type
= 1;
1441 work
->type_quals
|= code_for_qualifier (**mangled
);
1443 /* a qualified member function */
1444 if (oldmangled
== NULL
)
1445 oldmangled
= *mangled
;
1450 /* Local class name follows after "Lnnn_" */
1453 while (**mangled
&& (**mangled
!= '_'))
1464 case '0': case '1': case '2': case '3': case '4':
1465 case '5': case '6': case '7': case '8': case '9':
1466 if (oldmangled
== NULL
)
1468 oldmangled
= *mangled
;
1470 work
->temp_start
= -1; /* uppermost call to demangle_class */
1471 success
= demangle_class (work
, mangled
, declp
);
1474 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1476 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1478 /* EDG and others will have the "F", so we let the loop cycle
1479 if we are looking at one. */
1480 if (**mangled
!= 'F')
1489 success
= do_type (work
, mangled
, &s
);
1492 string_append (&s
, SCOPE_STRING (work
));
1493 string_prepends (declp
, &s
);
1503 /* ARM/HP style demangling includes a specific 'F' character after
1504 the class name. For GNU style, it is just implied. So we can
1505 safely just consume any 'F' at this point and be compatible
1506 with either style. */
1512 /* For lucid/ARM/HP style we have to forget any types we might
1513 have remembered up to this point, since they were not argument
1514 types. GNU style considers all types seen as available for
1515 back references. See comment in demangle_args() */
1517 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1519 forget_types (work
);
1521 success
= demangle_args (work
, mangled
, declp
);
1522 /* After picking off the function args, we expect to either
1523 find the function return type (preceded by an '_') or the
1524 end of the string. */
1525 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1528 /* At this level, we do not care about the return type. */
1529 success
= do_type (work
, mangled
, &tname
);
1530 string_delete (&tname
);
1537 string_init(&trawname
);
1538 string_init(&tname
);
1539 if (oldmangled
== NULL
)
1541 oldmangled
= *mangled
;
1543 success
= demangle_template (work
, mangled
, &tname
,
1547 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1549 string_append (&tname
, SCOPE_STRING (work
));
1551 string_prepends(declp
, &tname
);
1552 if (work
-> destructor
& 1)
1554 string_prepend (&trawname
, "~");
1555 string_appends (declp
, &trawname
);
1556 work
->destructor
-= 1;
1558 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1560 string_appends (declp
, &trawname
);
1561 work
->constructor
-= 1;
1563 string_delete(&trawname
);
1564 string_delete(&tname
);
1570 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1572 /* Read the return type. */
1576 success
= do_type (work
, mangled
, &return_type
);
1577 APPEND_BLANK (&return_type
);
1579 string_prepends (declp
, &return_type
);
1580 string_delete (&return_type
);
1584 /* At the outermost level, we cannot have a return type specified,
1585 so if we run into another '_' at this point we are dealing with
1586 a mangled name that is either bogus, or has been mangled by
1587 some algorithm we don't know how to deal with. So just
1588 reject the entire demangling. */
1589 /* However, "_nnn" is an expected suffix for alternate entry point
1590 numbered nnn for a function, with HP aCC, so skip over that
1591 without reporting failure. pai/1997-09-04 */
1595 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1603 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1605 /* A G++ template function. Read the template arguments. */
1606 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1608 if (!(work
->constructor
& 1))
1609 expect_return_type
= 1;
1618 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1620 /* Assume we have stumbled onto the first outermost function
1621 argument token, and start processing args. */
1623 success
= demangle_args (work
, mangled
, declp
);
1627 /* Non-GNU demanglers use a specific token to mark the start
1628 of the outermost function argument tokens. Typically 'F',
1629 for ARM/HP-demangling, for example. So if we find something
1630 we are not prepared for, it must be an error. */
1636 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1639 if (success
&& expect_func
)
1642 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1644 forget_types (work
);
1646 success
= demangle_args (work
, mangled
, declp
);
1647 /* Since template include the mangling of their return types,
1648 we must set expect_func to 0 so that we don't try do
1649 demangle more arguments the next time we get here. */
1654 if (success
&& !func_done
)
1656 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1658 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1659 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1660 first case, and need to ensure that the '(void)' gets added to
1661 the current declp. Note that with ARM/HP, the first case
1662 represents the name of a static data member 'foo::bar',
1663 which is in the current declp, so we leave it alone. */
1664 success
= demangle_args (work
, mangled
, declp
);
1667 if (success
&& PRINT_ARG_TYPES
)
1669 if (work
->static_type
)
1670 string_append (declp
, " static");
1671 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1673 APPEND_BLANK (declp
);
1674 string_append (declp
, qualifier_string (work
->type_quals
));
1684 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1689 if (work
-> static_type
)
1691 string_append (declp
, *mangled
+ 1);
1692 *mangled
+= strlen (*mangled
);
1697 success
= demangle_args (work
, mangled
, declp
);
1705 demangle_template_template_parm (struct work_stuff
*work
,
1706 const char **mangled
, string
*tname
)
1714 string_append (tname
, "template <");
1715 /* get size of template parameter list */
1716 if (get_count (mangled
, &r
))
1718 for (i
= 0; i
< r
; i
++)
1722 string_append (tname
, ", ");
1725 /* Z for type parameters */
1726 if (**mangled
== 'Z')
1729 string_append (tname
, "class");
1731 /* z for template parameters */
1732 else if (**mangled
== 'z')
1736 demangle_template_template_parm (work
, mangled
, tname
);
1744 /* temp is initialized in do_type */
1745 success
= do_type (work
, mangled
, &temp
);
1748 string_appends (tname
, &temp
);
1750 string_delete(&temp
);
1760 if (tname
->p
[-1] == '>')
1761 string_append (tname
, " ");
1762 string_append (tname
, "> class");
1767 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1768 string
*s
, type_kind_t tk
)
1770 int need_operator
= 0;
1774 string_appendn (s
, "(", 1);
1776 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1785 len
= strlen (*mangled
);
1787 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1789 size_t l
= strlen (optable
[i
].in
);
1792 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1794 string_appendn (s
, " ", 1);
1795 string_append (s
, optable
[i
].out
);
1796 string_appendn (s
, " ", 1);
1809 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1812 if (**mangled
!= 'W')
1816 string_appendn (s
, ")", 1);
1824 demangle_integral_value (struct work_stuff
*work
,
1825 const char **mangled
, string
*s
)
1829 if (**mangled
== 'E')
1830 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1831 else if (**mangled
== 'Q' || **mangled
== 'K')
1832 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1837 /* By default, we let the number decide whether we shall consume an
1839 int multidigit_without_leading_underscore
= 0;
1840 int leave_following_underscore
= 0;
1844 if (**mangled
== '_')
1846 if (mangled
[0][1] == 'm')
1848 /* Since consume_count_with_underscores does not handle the
1849 `m'-prefix we must do it here, using consume_count and
1850 adjusting underscores: we have to consume the underscore
1851 matching the prepended one. */
1852 multidigit_without_leading_underscore
= 1;
1853 string_appendn (s
, "-", 1);
1858 /* Do not consume a following underscore;
1859 consume_count_with_underscores will consume what
1860 should be consumed. */
1861 leave_following_underscore
= 1;
1866 /* Negative numbers are indicated with a leading `m'. */
1867 if (**mangled
== 'm')
1869 string_appendn (s
, "-", 1);
1872 /* Since consume_count_with_underscores does not handle
1873 multi-digit numbers that do not start with an underscore,
1874 and this number can be an integer template parameter,
1875 we have to call consume_count. */
1876 multidigit_without_leading_underscore
= 1;
1877 /* These multi-digit numbers never end on an underscore,
1878 so if there is one then don't eat it. */
1879 leave_following_underscore
= 1;
1882 /* We must call consume_count if we expect to remove a trailing
1883 underscore, since consume_count_with_underscores expects
1884 the leading underscore (that we consumed) if it is to handle
1885 multi-digit numbers. */
1886 if (multidigit_without_leading_underscore
)
1887 value
= consume_count (mangled
);
1889 value
= consume_count_with_underscores (mangled
);
1893 char buf
[INTBUF_SIZE
];
1894 sprintf (buf
, "%d", value
);
1895 string_append (s
, buf
);
1897 /* Numbers not otherwise delimited, might have an underscore
1898 appended as a delimeter, which we should skip.
1900 ??? This used to always remove a following underscore, which
1901 is wrong. If other (arbitrary) cases are followed by an
1902 underscore, we need to do something more radical. */
1904 if ((value
> 9 || multidigit_without_leading_underscore
)
1905 && ! leave_following_underscore
1906 && **mangled
== '_')
1917 /* Demangle the real value in MANGLED. */
1920 demangle_real_value (struct work_stuff
*work
,
1921 const char **mangled
, string
*s
)
1923 if (**mangled
== 'E')
1924 return demangle_expression (work
, mangled
, s
, tk_real
);
1926 if (**mangled
== 'm')
1928 string_appendn (s
, "-", 1);
1931 while (ISDIGIT ((unsigned char)**mangled
))
1933 string_appendn (s
, *mangled
, 1);
1936 if (**mangled
== '.') /* fraction */
1938 string_appendn (s
, ".", 1);
1940 while (ISDIGIT ((unsigned char)**mangled
))
1942 string_appendn (s
, *mangled
, 1);
1946 if (**mangled
== 'e') /* exponent */
1948 string_appendn (s
, "e", 1);
1950 while (ISDIGIT ((unsigned char)**mangled
))
1952 string_appendn (s
, *mangled
, 1);
1961 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
1962 string
*s
, type_kind_t tk
)
1966 if (**mangled
== 'Y')
1968 /* The next argument is a template parameter. */
1972 idx
= consume_count_with_underscores (mangled
);
1974 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1975 || consume_count_with_underscores (mangled
) == -1)
1977 if (work
->tmpl_argvec
)
1978 string_append (s
, work
->tmpl_argvec
[idx
]);
1980 string_append_template_idx (s
, idx
);
1982 else if (tk
== tk_integral
)
1983 success
= demangle_integral_value (work
, mangled
, s
);
1984 else if (tk
== tk_char
)
1988 if (**mangled
== 'm')
1990 string_appendn (s
, "-", 1);
1993 string_appendn (s
, "'", 1);
1994 val
= consume_count(mangled
);
2001 string_appendn (s
, &tmp
[0], 1);
2002 string_appendn (s
, "'", 1);
2005 else if (tk
== tk_bool
)
2007 int val
= consume_count (mangled
);
2009 string_appendn (s
, "false", 5);
2011 string_appendn (s
, "true", 4);
2015 else if (tk
== tk_real
)
2016 success
= demangle_real_value (work
, mangled
, s
);
2017 else if (tk
== tk_pointer
|| tk
== tk_reference
)
2019 if (**mangled
== 'Q')
2020 success
= demangle_qualified (work
, mangled
, s
,
2025 int symbol_len
= consume_count (mangled
);
2026 if (symbol_len
== -1)
2028 if (symbol_len
== 0)
2029 string_appendn (s
, "0", 1);
2032 char *p
= XNEWVEC (char, symbol_len
+ 1), *q
;
2033 strncpy (p
, *mangled
, symbol_len
);
2034 p
[symbol_len
] = '\0';
2035 /* We use cplus_demangle here, rather than
2036 internal_cplus_demangle, because the name of the entity
2037 mangled here does not make use of any of the squangling
2038 or type-code information we have built up thus far; it is
2039 mangled independently. */
2040 q
= cplus_demangle (p
, work
->options
);
2041 if (tk
== tk_pointer
)
2042 string_appendn (s
, "&", 1);
2043 /* FIXME: Pointer-to-member constants should get a
2044 qualifying class name here. */
2047 string_append (s
, q
);
2051 string_append (s
, p
);
2054 *mangled
+= symbol_len
;
2061 /* Demangle the template name in MANGLED. The full name of the
2062 template (e.g., S<int>) is placed in TNAME. The name without the
2063 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2064 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2065 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2066 the template is remembered in the list of back-referenceable
2070 demangle_template (struct work_stuff
*work
, const char **mangled
,
2071 string
*tname
, string
*trawname
,
2072 int is_type
, int remember
)
2078 int is_java_array
= 0;
2084 /* get template name */
2085 if (**mangled
== 'z')
2091 idx
= consume_count_with_underscores (mangled
);
2093 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2094 || consume_count_with_underscores (mangled
) == -1)
2097 if (work
->tmpl_argvec
)
2099 string_append (tname
, work
->tmpl_argvec
[idx
]);
2101 string_append (trawname
, work
->tmpl_argvec
[idx
]);
2105 string_append_template_idx (tname
, idx
);
2107 string_append_template_idx (trawname
, idx
);
2112 if ((r
= consume_count (mangled
)) <= 0
2113 || (int) strlen (*mangled
) < r
)
2117 is_java_array
= (work
-> options
& DMGL_JAVA
)
2118 && strncmp (*mangled
, "JArray1Z", 8) == 0;
2119 if (! is_java_array
)
2121 string_appendn (tname
, *mangled
, r
);
2124 string_appendn (trawname
, *mangled
, r
);
2129 string_append (tname
, "<");
2130 /* get size of template parameter list */
2131 if (!get_count (mangled
, &r
))
2137 /* Create an array for saving the template argument values. */
2138 work
->tmpl_argvec
= XNEWVEC (char *, r
);
2139 work
->ntmpl_args
= r
;
2140 for (i
= 0; i
< r
; i
++)
2141 work
->tmpl_argvec
[i
] = 0;
2143 for (i
= 0; i
< r
; i
++)
2147 string_append (tname
, ", ");
2149 /* Z for type parameters */
2150 if (**mangled
== 'Z')
2153 /* temp is initialized in do_type */
2154 success
= do_type (work
, mangled
, &temp
);
2157 string_appends (tname
, &temp
);
2161 /* Save the template argument. */
2162 int len
= temp
.p
- temp
.b
;
2163 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2164 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2165 work
->tmpl_argvec
[i
][len
] = '\0';
2168 string_delete(&temp
);
2174 /* z for template parameters */
2175 else if (**mangled
== 'z')
2179 success
= demangle_template_template_parm (work
, mangled
, tname
);
2182 && (r2
= consume_count (mangled
)) > 0
2183 && (int) strlen (*mangled
) >= r2
)
2185 string_append (tname
, " ");
2186 string_appendn (tname
, *mangled
, r2
);
2189 /* Save the template argument. */
2191 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2192 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2193 work
->tmpl_argvec
[i
][len
] = '\0';
2207 /* otherwise, value parameter */
2209 /* temp is initialized in do_type */
2210 success
= do_type (work
, mangled
, &temp
);
2211 string_delete(&temp
);
2223 success
= demangle_template_value_parm (work
, mangled
, s
,
2224 (type_kind_t
) success
);
2236 int len
= s
->p
- s
->b
;
2237 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2238 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2239 work
->tmpl_argvec
[i
][len
] = '\0';
2241 string_appends (tname
, s
);
2249 string_append (tname
, "[]");
2253 if (tname
->p
[-1] == '>')
2254 string_append (tname
, " ");
2255 string_append (tname
, ">");
2258 if (is_type
&& remember
)
2260 const int bindex
= register_Btype (work
);
2261 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2265 if (work -> static_type)
2267 string_append (declp, *mangled + 1);
2268 *mangled += strlen (*mangled);
2273 success = demangle_args (work, mangled, declp);
2281 arm_pt (struct work_stuff
*work
, const char *mangled
,
2282 int n
, const char **anchor
, const char **args
)
2284 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2285 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2286 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2289 *args
= *anchor
+ 6;
2290 len
= consume_count (args
);
2293 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2299 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2301 if ((*anchor
= strstr (mangled
, "__tm__"))
2302 || (*anchor
= strstr (mangled
, "__ps__"))
2303 || (*anchor
= strstr (mangled
, "__pt__")))
2306 *args
= *anchor
+ 6;
2307 len
= consume_count (args
);
2310 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2316 else if ((*anchor
= strstr (mangled
, "__S")))
2319 *args
= *anchor
+ 3;
2320 len
= consume_count (args
);
2323 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2335 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2336 int n
, string
*declp
)
2340 const char *e
= *mangled
+ n
;
2343 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2345 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2347 char *start_spec_args
= NULL
;
2350 /* First check for and omit template specialization pseudo-arguments,
2351 such as in "Spec<#1,#1.*>" */
2352 start_spec_args
= strchr (*mangled
, '<');
2353 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2354 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2356 string_appendn (declp
, *mangled
, n
);
2357 (*mangled
) += n
+ 1;
2359 if (work
->temp_start
== -1) /* non-recursive call */
2360 work
->temp_start
= declp
->p
- declp
->b
;
2362 /* We want to unconditionally demangle parameter types in
2363 template parameters. */
2364 hold_options
= work
->options
;
2365 work
->options
|= DMGL_PARAMS
;
2367 string_append (declp
, "<");
2370 string_delete (&arg
);
2374 /* 'T' signals a type parameter */
2376 if (!do_type (work
, mangled
, &arg
))
2377 goto hpacc_template_args_done
;
2382 /* 'U' or 'S' signals an integral value */
2383 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2384 goto hpacc_template_args_done
;
2388 /* 'A' signals a named constant expression (literal) */
2389 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2390 goto hpacc_template_args_done
;
2394 /* Today, 1997-09-03, we have only the above types
2395 of template parameters */
2396 /* FIXME: maybe this should fail and return null */
2397 goto hpacc_template_args_done
;
2399 string_appends (declp
, &arg
);
2400 /* Check if we're at the end of template args.
2401 0 if at end of static member of template class,
2402 _ if done with template args for a function */
2403 if ((**mangled
== '\000') || (**mangled
== '_'))
2406 string_append (declp
, ",");
2408 hpacc_template_args_done
:
2409 string_append (declp
, ">");
2410 string_delete (&arg
);
2411 if (**mangled
== '_')
2413 work
->options
= hold_options
;
2416 /* ARM template? (Also handles HP cfront extensions) */
2417 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2423 string_appendn (declp
, *mangled
, p
- *mangled
);
2424 if (work
->temp_start
== -1) /* non-recursive call */
2425 work
->temp_start
= declp
->p
- declp
->b
;
2427 /* We want to unconditionally demangle parameter types in
2428 template parameters. */
2429 hold_options
= work
->options
;
2430 work
->options
|= DMGL_PARAMS
;
2432 string_append (declp
, "<");
2433 /* should do error checking here */
2435 string_delete (&arg
);
2437 /* Check for type or literal here */
2440 /* HP cfront extensions to ARM for template args */
2441 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2442 /* FIXME: We handle only numeric literals for HP cfront */
2444 /* A typed constant value follows */
2446 if (!do_type (work
, &args
, &type_str
))
2447 goto cfront_template_args_done
;
2448 string_append (&arg
, "(");
2449 string_appends (&arg
, &type_str
);
2450 string_delete (&type_str
);
2451 string_append (&arg
, ")");
2453 goto cfront_template_args_done
;
2455 /* Now snarf a literal value following 'L' */
2456 if (!snarf_numeric_literal (&args
, &arg
))
2457 goto cfront_template_args_done
;
2461 /* Snarf a literal following 'L' */
2463 if (!snarf_numeric_literal (&args
, &arg
))
2464 goto cfront_template_args_done
;
2467 /* Not handling other HP cfront stuff */
2469 const char* old_args
= args
;
2470 if (!do_type (work
, &args
, &arg
))
2471 goto cfront_template_args_done
;
2473 /* Fail if we didn't make any progress: prevent infinite loop. */
2474 if (args
== old_args
)
2476 work
->options
= hold_options
;
2481 string_appends (declp
, &arg
);
2482 string_append (declp
, ",");
2484 cfront_template_args_done
:
2485 string_delete (&arg
);
2487 --declp
->p
; /* remove extra comma */
2488 string_append (declp
, ">");
2489 work
->options
= hold_options
;
2491 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2492 && (*mangled
)[9] == 'N'
2493 && (*mangled
)[8] == (*mangled
)[10]
2494 && strchr (cplus_markers
, (*mangled
)[8]))
2496 /* A member of the anonymous namespace. */
2497 string_append (declp
, "{anonymous}");
2501 if (work
->temp_start
== -1) /* non-recursive call only */
2502 work
->temp_start
= 0; /* disable in recursive calls */
2503 string_appendn (declp
, *mangled
, n
);
2508 /* Extract a class name, possibly a template with arguments, from the
2509 mangled string; qualifiers, local class indicators, etc. have
2510 already been dealt with */
2513 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2519 n
= consume_count (mangled
);
2522 if ((int) strlen (*mangled
) >= n
)
2524 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2535 demangle_class -- demangle a mangled class sequence
2540 demangle_class (struct work_stuff *work, const char **mangled,
2545 DECLP points to the buffer into which demangling is being done.
2547 *MANGLED points to the current token to be demangled. On input,
2548 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2549 On exit, it points to the next token after the mangled class on
2550 success, or the first unconsumed token on failure.
2552 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2553 we are demangling a constructor or destructor. In this case
2554 we prepend "class::class" or "class::~class" to DECLP.
2556 Otherwise, we prepend "class::" to the current DECLP.
2558 Reset the constructor/destructor flags once they have been
2559 "consumed". This allows demangle_class to be called later during
2560 the same demangling, to do normal class demangling.
2562 Returns 1 if demangling is successful, 0 otherwise.
2567 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2572 char *save_class_name_end
= 0;
2574 string_init (&class_name
);
2575 btype
= register_Btype (work
);
2576 if (demangle_class_name (work
, mangled
, &class_name
))
2578 save_class_name_end
= class_name
.p
;
2579 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2581 /* adjust so we don't include template args */
2582 if (work
->temp_start
&& (work
->temp_start
!= -1))
2584 class_name
.p
= class_name
.b
+ work
->temp_start
;
2586 string_prepends (declp
, &class_name
);
2587 if (work
-> destructor
& 1)
2589 string_prepend (declp
, "~");
2590 work
-> destructor
-= 1;
2594 work
-> constructor
-= 1;
2597 class_name
.p
= save_class_name_end
;
2598 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2599 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2600 string_prepend (declp
, SCOPE_STRING (work
));
2601 string_prepends (declp
, &class_name
);
2604 string_delete (&class_name
);
2609 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2610 the rightmost guess.
2612 Find the correct "__"-sequence where the function name ends and the
2613 signature starts, which is ambiguous with GNU mangling.
2614 Call demangle_signature here, so we can make sure we found the right
2615 one; *mangled will be consumed so caller will not make further calls to
2616 demangle_signature. */
2619 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2620 string
*declp
, const char *scan
)
2622 const char *mangle_init
= *mangled
;
2625 struct work_stuff work_init
;
2627 if (*(scan
+ 2) == '\0')
2630 /* Do not iterate for some demangling modes, or if there's only one
2631 "__"-sequence. This is the normal case. */
2632 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2633 || strstr (scan
+ 2, "__") == NULL
)
2634 return demangle_function_name (work
, mangled
, declp
, scan
);
2636 /* Save state so we can restart if the guess at the correct "__" was
2638 string_init (&decl_init
);
2639 string_appends (&decl_init
, declp
);
2640 memset (&work_init
, 0, sizeof work_init
);
2641 work_stuff_copy_to_from (&work_init
, work
);
2643 /* Iterate over occurrences of __, allowing names and types to have a
2644 "__" sequence in them. We must start with the first (not the last)
2645 occurrence, since "__" most often occur between independent mangled
2646 parts, hence starting at the last occurence inside a signature
2647 might get us a "successful" demangling of the signature. */
2651 if (demangle_function_name (work
, mangled
, declp
, scan
))
2653 success
= demangle_signature (work
, mangled
, declp
);
2658 /* Reset demangle state for the next round. */
2659 *mangled
= mangle_init
;
2660 string_clear (declp
);
2661 string_appends (declp
, &decl_init
);
2662 work_stuff_copy_to_from (work
, &work_init
);
2664 /* Leave this underscore-sequence. */
2667 /* Scan for the next "__" sequence. */
2668 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2671 /* Move to last "__" in this sequence. */
2672 while (*scan
&& *scan
== '_')
2677 /* Delete saved state. */
2678 delete_work_stuff (&work_init
);
2679 string_delete (&decl_init
);
2688 demangle_prefix -- consume the mangled name prefix and find signature
2693 demangle_prefix (struct work_stuff *work, const char **mangled,
2698 Consume and demangle the prefix of the mangled name.
2699 While processing the function name root, arrange to call
2700 demangle_signature if the root is ambiguous.
2702 DECLP points to the string buffer into which demangled output is
2703 placed. On entry, the buffer is empty. On exit it contains
2704 the root function name, the demangled operator name, or in some
2705 special cases either nothing or the completely demangled result.
2707 MANGLED points to the current pointer into the mangled name. As each
2708 token of the mangled name is consumed, it is updated. Upon entry
2709 the current mangled name pointer points to the first character of
2710 the mangled name. Upon exit, it should point to the first character
2711 of the signature if demangling was successful, or to the first
2712 unconsumed character if demangling of the prefix was unsuccessful.
2714 Returns 1 on success, 0 otherwise.
2718 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2725 if (strlen(*mangled
) > 6
2726 && (strncmp(*mangled
, "_imp__", 6) == 0
2727 || strncmp(*mangled
, "__imp_", 6) == 0))
2729 /* it's a symbol imported from a PE dynamic library. Check for both
2730 new style prefix _imp__ and legacy __imp_ used by older versions
2733 work
->dllimported
= 1;
2735 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2737 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2738 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2740 if ((*mangled
)[9] == 'D')
2742 /* it's a GNU global destructor to be executed at program exit */
2744 work
->destructor
= 2;
2745 if (gnu_special (work
, mangled
, declp
))
2748 else if ((*mangled
)[9] == 'I')
2750 /* it's a GNU global constructor to be executed at program init */
2752 work
->constructor
= 2;
2753 if (gnu_special (work
, mangled
, declp
))
2758 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2760 /* it's a ARM global destructor to be executed at program exit */
2762 work
->destructor
= 2;
2764 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2766 /* it's a ARM global constructor to be executed at program initial */
2768 work
->constructor
= 2;
2771 /* This block of code is a reduction in strength time optimization
2773 scan = strstr (*mangled, "__"); */
2779 scan
= strchr (scan
, '_');
2780 } while (scan
!= NULL
&& *++scan
!= '_');
2782 if (scan
!= NULL
) --scan
;
2787 /* We found a sequence of two or more '_', ensure that we start at
2788 the last pair in the sequence. */
2789 i
= strspn (scan
, "_");
2800 else if (work
-> static_type
)
2802 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2807 else if ((scan
== *mangled
)
2808 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2809 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2811 /* The ARM says nothing about the mangling of local variables.
2812 But cfront mangles local variables by prepending __<nesting_level>
2813 to them. As an extension to ARM demangling we handle this case. */
2814 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2815 && ISDIGIT ((unsigned char)scan
[2]))
2817 *mangled
= scan
+ 2;
2818 consume_count (mangled
);
2819 string_append (declp
, *mangled
);
2820 *mangled
+= strlen (*mangled
);
2825 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2826 names like __Q2_3foo3bar for nested type names. So don't accept
2827 this style of constructor for cfront demangling. A GNU
2828 style member-template constructor starts with 'H'. */
2829 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2830 work
-> constructor
+= 1;
2831 *mangled
= scan
+ 2;
2834 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2836 /* Cfront-style parameterized type. Handled later as a signature. */
2840 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2842 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2843 || (scan
[2] == 'p' && scan
[3] == 's')
2844 || (scan
[2] == 'p' && scan
[3] == 't')))
2846 /* EDG-style parameterized type. Handled later as a signature. */
2850 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2852 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2853 && (scan
[2] != 't'))
2855 /* Mangled name starts with "__". Skip over any leading '_' characters,
2856 then find the next "__" that separates the prefix from the signature.
2858 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2859 || (arm_special (mangled
, declp
) == 0))
2861 while (*scan
== '_')
2865 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2867 /* No separator (I.E. "__not_mangled"), or empty signature
2868 (I.E. "__not_mangled_either__") */
2872 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2875 else if (*(scan
+ 2) != '\0')
2877 /* Mangled name does not start with "__" but does have one somewhere
2878 in there with non empty stuff after it. Looks like a global
2879 function name. Iterate over all "__":s until the right
2881 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2885 /* Doesn't look like a mangled name */
2889 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2891 string_append (declp
, *mangled
);
2892 *mangled
+= strlen (*mangled
);
2902 gnu_special -- special handling of gnu mangled strings
2907 gnu_special (struct work_stuff *work, const char **mangled,
2913 Process some special GNU style mangling forms that don't fit
2914 the normal pattern. For example:
2916 _$_3foo (destructor for class foo)
2917 _vt$foo (foo virtual table)
2918 _vt$foo$bar (foo::bar virtual table)
2919 __vt_foo (foo virtual table, new style with thunks)
2920 _3foo$varname (static data member)
2921 _Q22rs2tu$vw (static data member)
2922 __t6vector1Zii (constructor with template)
2923 __thunk_4__$_7ostream (virtual function thunk)
2927 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2933 if ((*mangled
)[0] == '_'
2934 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2935 && (*mangled
)[2] == '_')
2937 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2939 work
-> destructor
+= 1;
2941 else if ((*mangled
)[0] == '_'
2942 && (((*mangled
)[1] == '_'
2943 && (*mangled
)[2] == 'v'
2944 && (*mangled
)[3] == 't'
2945 && (*mangled
)[4] == '_')
2946 || ((*mangled
)[1] == 'v'
2947 && (*mangled
)[2] == 't'
2948 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2950 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2951 and create the decl. Note that we consume the entire mangled
2952 input string, which means that demangle_signature has no work
2954 if ((*mangled
)[2] == 'v')
2955 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2957 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2958 while (**mangled
!= '\0')
2964 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2967 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2971 if (ISDIGIT((unsigned char)*mangled
[0]))
2973 n
= consume_count(mangled
);
2974 /* We may be seeing a too-large size, or else a
2975 ".<digits>" indicating a static local symbol. In
2976 any case, declare victory and move on; *don't* try
2977 to use n to allocate. */
2978 if (n
> (int) strlen (*mangled
))
2986 n
= strcspn (*mangled
, cplus_markers
);
2988 string_appendn (declp
, *mangled
, n
);
2992 p
= strpbrk (*mangled
, cplus_markers
);
2993 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2997 string_append (declp
, SCOPE_STRING (work
));
3008 string_append (declp
, " virtual table");
3010 else if ((*mangled
)[0] == '_'
3011 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
3012 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
3014 /* static data member, "_3foo$varname" for example */
3020 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3023 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3026 n
= consume_count (mangled
);
3027 if (n
< 0 || n
> (long) strlen (*mangled
))
3033 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
3034 && (*mangled
)[9] == 'N'
3035 && (*mangled
)[8] == (*mangled
)[10]
3036 && strchr (cplus_markers
, (*mangled
)[8]))
3038 /* A member of the anonymous namespace. There's information
3039 about what identifier or filename it was keyed to, but
3040 it's just there to make the mangled name unique; we just
3042 string_append (declp
, "{anonymous}");
3045 /* Now p points to the marker before the N, so we need to
3046 update it to the first marker after what we consumed. */
3047 p
= strpbrk (*mangled
, cplus_markers
);
3051 string_appendn (declp
, *mangled
, n
);
3054 if (success
&& (p
== *mangled
))
3056 /* Consumed everything up to the cplus_marker, append the
3059 string_append (declp
, SCOPE_STRING (work
));
3060 n
= strlen (*mangled
);
3061 string_appendn (declp
, *mangled
, n
);
3069 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
3074 delta
= consume_count (mangled
);
3079 char *method
= internal_cplus_demangle (work
, ++*mangled
);
3084 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
3085 string_append (declp
, buf
);
3086 string_append (declp
, method
);
3088 n
= strlen (*mangled
);
3097 else if (strncmp (*mangled
, "__t", 3) == 0
3098 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
3100 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
3106 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3109 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3112 success
= do_type (work
, mangled
, declp
);
3115 if (success
&& **mangled
!= '\0')
3118 string_append (declp
, p
);
3128 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
3129 string
*result
, int namelength
)
3131 char * recurse
= (char *)NULL
;
3132 char * recurse_dem
= (char *)NULL
;
3134 recurse
= XNEWVEC (char, namelength
+ 1);
3135 memcpy (recurse
, *mangled
, namelength
);
3136 recurse
[namelength
] = '\000';
3138 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3142 string_append (result
, recurse_dem
);
3147 string_appendn (result
, *mangled
, namelength
);
3150 *mangled
+= namelength
;
3157 arm_special -- special handling of ARM/lucid mangled strings
3162 arm_special (const char **mangled,
3168 Process some special ARM style mangling forms that don't fit
3169 the normal pattern. For example:
3171 __vtbl__3foo (foo virtual table)
3172 __vtbl__3foo__3bar (bar::foo virtual table)
3177 arm_special (const char **mangled
, string
*declp
)
3183 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3185 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3186 and create the decl. Note that we consume the entire mangled
3187 input string, which means that demangle_signature has no work
3189 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3190 while (*scan
!= '\0') /* first check it can be demangled */
3192 n
= consume_count (&scan
);
3195 return (0); /* no good */
3198 if (scan
[0] == '_' && scan
[1] == '_')
3203 (*mangled
) += ARM_VTABLE_STRLEN
;
3204 while (**mangled
!= '\0')
3206 n
= consume_count (mangled
);
3208 || n
> (long) strlen (*mangled
))
3210 string_prependn (declp
, *mangled
, n
);
3212 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3214 string_prepend (declp
, "::");
3218 string_append (declp
, " virtual table");
3231 demangle_qualified -- demangle 'Q' qualified name strings
3236 demangle_qualified (struct work_stuff *, const char *mangled,
3237 string *result, int isfuncname, int append);
3241 Demangle a qualified name, such as "Q25Outer5Inner" which is
3242 the mangled form of "Outer::Inner". The demangled output is
3243 prepended or appended to the result string according to the
3244 state of the append flag.
3246 If isfuncname is nonzero, then the qualified name we are building
3247 is going to be used as a member function name, so if it is a
3248 constructor or destructor function, append an appropriate
3249 constructor or destructor name. I.E. for the above example,
3250 the result for use as a constructor is "Outer::Inner::Inner"
3251 and the result for use as a destructor is "Outer::Inner::~Inner".
3255 Numeric conversion is ASCII dependent (FIXME).
3260 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3261 string
*result
, int isfuncname
, int append
)
3268 int bindex
= register_Btype (work
);
3270 /* We only make use of ISFUNCNAME if the entity is a constructor or
3272 isfuncname
= (isfuncname
3273 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3275 string_init (&temp
);
3276 string_init (&last_name
);
3278 if ((*mangled
)[0] == 'K')
3280 /* Squangling qualified name reuse */
3283 idx
= consume_count_with_underscores (mangled
);
3284 if (idx
== -1 || idx
>= work
-> numk
)
3287 string_append (&temp
, work
-> ktypevec
[idx
]);
3290 switch ((*mangled
)[1])
3293 /* GNU mangled name with more than 9 classes. The count is preceded
3294 by an underscore (to distinguish it from the <= 9 case) and followed
3295 by an underscore. */
3297 qualifiers
= consume_count_with_underscores (mangled
);
3298 if (qualifiers
== -1)
3311 /* The count is in a single digit. */
3312 num
[0] = (*mangled
)[1];
3314 qualifiers
= atoi (num
);
3316 /* If there is an underscore after the digit, skip it. This is
3317 said to be for ARM-qualified names, but the ARM makes no
3318 mention of such an underscore. Perhaps cfront uses one. */
3319 if ((*mangled
)[2] == '_')
3334 /* Pick off the names and collect them in the temp buffer in the order
3335 in which they are found, separated by '::'. */
3337 while (qualifiers
-- > 0)
3340 string_clear (&last_name
);
3342 if (*mangled
[0] == '_')
3345 if (*mangled
[0] == 't')
3347 /* Here we always append to TEMP since we will want to use
3348 the template name without the template parameters as a
3349 constructor or destructor name. The appropriate
3350 (parameter-less) value is returned by demangle_template
3351 in LAST_NAME. We do not remember the template type here,
3352 in order to match the G++ mangling algorithm. */
3353 success
= demangle_template(work
, mangled
, &temp
,
3358 else if (*mangled
[0] == 'K')
3362 idx
= consume_count_with_underscores (mangled
);
3363 if (idx
== -1 || idx
>= work
->numk
)
3366 string_append (&temp
, work
->ktypevec
[idx
]);
3369 if (!success
) break;
3376 /* Now recursively demangle the qualifier
3377 * This is necessary to deal with templates in
3378 * mangling styles like EDG */
3379 namelength
= consume_count (mangled
);
3380 if (namelength
== -1)
3385 recursively_demangle(work
, mangled
, &temp
, namelength
);
3389 string_delete (&last_name
);
3390 success
= do_type (work
, mangled
, &last_name
);
3393 string_appends (&temp
, &last_name
);
3398 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3401 string_append (&temp
, SCOPE_STRING (work
));
3404 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3406 /* If we are using the result as a function name, we need to append
3407 the appropriate '::' separated constructor or destructor name.
3408 We do this here because this is the most convenient place, where
3409 we already have a pointer to the name and the length of the name. */
3413 string_append (&temp
, SCOPE_STRING (work
));
3414 if (work
-> destructor
& 1)
3415 string_append (&temp
, "~");
3416 string_appends (&temp
, &last_name
);
3419 /* Now either prepend the temp buffer to the result, or append it,
3420 depending upon the state of the append flag. */
3423 string_appends (result
, &temp
);
3426 if (!STRING_EMPTY (result
))
3427 string_append (&temp
, SCOPE_STRING (work
));
3428 string_prepends (result
, &temp
);
3431 string_delete (&last_name
);
3432 string_delete (&temp
);
3440 get_count -- convert an ascii count to integer, consuming tokens
3445 get_count (const char **type, int *count)
3449 Assume that *type points at a count in a mangled name; set
3450 *count to its value, and set *type to the next character after
3451 the count. There are some weird rules in effect here.
3453 If *type does not point at a string of digits, return zero.
3455 If *type points at a string of digits followed by an
3456 underscore, set *count to their value as an integer, advance
3457 *type to point *after the underscore, and return 1.
3459 If *type points at a string of digits not followed by an
3460 underscore, consume only the first digit. Set *count to its
3461 value as an integer, leave *type pointing after that digit,
3464 The excuse for this odd behavior: in the ARM and HP demangling
3465 styles, a type can be followed by a repeat count of the form
3468 `x' is a single digit specifying how many additional copies
3469 of the type to append to the argument list, and
3471 `y' is one or more digits, specifying the zero-based index of
3472 the first repeated argument in the list. Yes, as you're
3473 unmangling the name you can figure this out yourself, but
3476 So, for example, in `bar__3fooFPiN51', the first argument is a
3477 pointer to an integer (`Pi'), and then the next five arguments
3478 are the same (`N5'), and the first repeat is the function's
3479 second argument (`1').
3483 get_count (const char **type
, int *count
)
3488 if (!ISDIGIT ((unsigned char)**type
))
3492 *count
= **type
- '0';
3494 if (ISDIGIT ((unsigned char)**type
))
3504 while (ISDIGIT ((unsigned char)*p
));
3515 /* RESULT will be initialised here; it will be freed on failure. The
3516 value returned is really a type_kind_t. */
3519 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3525 const char *remembered_type
;
3527 type_kind_t tk
= tk_none
;
3529 string_init (&decl
);
3530 string_init (result
);
3534 while (success
&& !done
)
3540 /* A pointer type */
3544 if (! (work
-> options
& DMGL_JAVA
))
3545 string_prepend (&decl
, "*");
3550 /* A reference type */
3553 string_prepend (&decl
, "&");
3562 if (!STRING_EMPTY (&decl
)
3563 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3565 string_prepend (&decl
, "(");
3566 string_append (&decl
, ")");
3568 string_append (&decl
, "[");
3569 if (**mangled
!= '_')
3570 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3572 if (**mangled
== '_')
3574 string_append (&decl
, "]");
3578 /* A back reference to a previously seen type */
3581 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3587 remembered_type
= work
-> typevec
[n
];
3588 mangled
= &remembered_type
;
3595 if (!STRING_EMPTY (&decl
)
3596 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3598 string_prepend (&decl
, "(");
3599 string_append (&decl
, ")");
3601 /* After picking off the function args, we expect to either find the
3602 function return type (preceded by an '_') or the end of the
3604 if (!demangle_nested_args (work
, mangled
, &decl
)
3605 || (**mangled
!= '_' && **mangled
!= '\0'))
3610 if (success
&& (**mangled
== '_'))
3617 type_quals
= TYPE_UNQUALIFIED
;
3619 member
= **mangled
== 'M';
3622 string_append (&decl
, ")");
3624 /* We don't need to prepend `::' for a qualified name;
3625 demangle_qualified will do that for us. */
3626 if (**mangled
!= 'Q')
3627 string_prepend (&decl
, SCOPE_STRING (work
));
3629 if (ISDIGIT ((unsigned char)**mangled
))
3631 n
= consume_count (mangled
);
3633 || (int) strlen (*mangled
) < n
)
3638 string_prependn (&decl
, *mangled
, n
);
3641 else if (**mangled
== 'X' || **mangled
== 'Y')
3644 do_type (work
, mangled
, &temp
);
3645 string_prepends (&decl
, &temp
);
3646 string_delete (&temp
);
3648 else if (**mangled
== 't')
3651 string_init (&temp
);
3652 success
= demangle_template (work
, mangled
, &temp
,
3656 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3657 string_delete (&temp
);
3662 else if (**mangled
== 'Q')
3664 success
= demangle_qualified (work
, mangled
, &decl
,
3676 string_prepend (&decl
, "(");
3684 type_quals
|= code_for_qualifier (**mangled
);
3692 if (*(*mangled
)++ != 'F')
3698 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3699 || **mangled
!= '_')
3705 if (! PRINT_ANSI_QUALIFIERS
)
3709 if (type_quals
!= TYPE_UNQUALIFIED
)
3711 APPEND_BLANK (&decl
);
3712 string_append (&decl
, qualifier_string (type_quals
));
3723 if (PRINT_ANSI_QUALIFIERS
)
3725 if (!STRING_EMPTY (&decl
))
3726 string_prepend (&decl
, " ");
3728 string_prepend (&decl
, demangle_qualifier (**mangled
));
3743 if (success
) switch (**mangled
)
3745 /* A qualified name, such as "Outer::Inner". */
3749 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3753 /* A back reference to a previously seen squangled type */
3756 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3759 string_append (result
, work
->btypevec
[n
]);
3764 /* A template parm. We substitute the corresponding argument. */
3769 idx
= consume_count_with_underscores (mangled
);
3772 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3773 || consume_count_with_underscores (mangled
) == -1)
3779 if (work
->tmpl_argvec
)
3780 string_append (result
, work
->tmpl_argvec
[idx
]);
3782 string_append_template_idx (result
, idx
);
3789 success
= demangle_fund_type (work
, mangled
, result
);
3791 tk
= (type_kind_t
) success
;
3797 if (!STRING_EMPTY (&decl
))
3799 string_append (result
, " ");
3800 string_appends (result
, &decl
);
3804 string_delete (result
);
3805 string_delete (&decl
);
3808 /* Assume an integral type, if we're not sure. */
3809 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3814 /* Given a pointer to a type string that represents a fundamental type
3815 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3816 string in which the demangled output is being built in RESULT, and
3817 the WORK structure, decode the types and add them to the result.
3822 "Sl" => "signed long"
3823 "CUs" => "const unsigned short"
3825 The value returned is really a type_kind_t. */
3828 demangle_fund_type (struct work_stuff
*work
,
3829 const char **mangled
, string
*result
)
3833 char buf
[INTBUF_SIZE
+ 5 /* 'int%u_t' */];
3834 unsigned int dec
= 0;
3835 type_kind_t tk
= tk_integral
;
3837 /* First pick off any type qualifiers. There can be more than one. */
3846 if (PRINT_ANSI_QUALIFIERS
)
3848 if (!STRING_EMPTY (result
))
3849 string_prepend (result
, " ");
3850 string_prepend (result
, demangle_qualifier (**mangled
));
3856 APPEND_BLANK (result
);
3857 string_append (result
, "unsigned");
3859 case 'S': /* signed char only */
3861 APPEND_BLANK (result
);
3862 string_append (result
, "signed");
3866 APPEND_BLANK (result
);
3867 string_append (result
, "__complex");
3875 /* Now pick off the fundamental type. There can be only one. */
3884 APPEND_BLANK (result
);
3885 string_append (result
, "void");
3889 APPEND_BLANK (result
);
3890 string_append (result
, "long long");
3894 APPEND_BLANK (result
);
3895 string_append (result
, "long");
3899 APPEND_BLANK (result
);
3900 string_append (result
, "int");
3904 APPEND_BLANK (result
);
3905 string_append (result
, "short");
3909 APPEND_BLANK (result
);
3910 string_append (result
, "bool");
3915 APPEND_BLANK (result
);
3916 string_append (result
, "char");
3921 APPEND_BLANK (result
);
3922 string_append (result
, "wchar_t");
3927 APPEND_BLANK (result
);
3928 string_append (result
, "long double");
3933 APPEND_BLANK (result
);
3934 string_append (result
, "double");
3939 APPEND_BLANK (result
);
3940 string_append (result
, "float");
3945 if (!ISDIGIT ((unsigned char)**mangled
))
3952 if (**mangled
== '_')
3957 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3960 if (**mangled
!= '_')
3970 strncpy (buf
, *mangled
, 2);
3972 *mangled
+= min (strlen (*mangled
), 2);
3974 sscanf (buf
, "%x", &dec
);
3975 sprintf (buf
, "int%u_t", dec
);
3976 APPEND_BLANK (result
);
3977 string_append (result
, buf
);
3981 /* An explicit type, such as "6mytype" or "7integer" */
3993 int bindex
= register_Btype (work
);
3995 string_init (&btype
);
3996 if (demangle_class_name (work
, mangled
, &btype
)) {
3997 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3998 APPEND_BLANK (result
);
3999 string_appends (result
, &btype
);
4003 string_delete (&btype
);
4009 string_init (&btype
);
4010 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
4011 string_appends (result
, &btype
);
4012 string_delete (&btype
);
4020 return success
? ((int) tk
) : 0;
4024 /* Handle a template's value parameter for HP aCC (extension from ARM)
4025 **mangled points to 'S' or 'U' */
4028 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
4029 const char **mangled
, string
*result
)
4033 if (**mangled
!= 'U' && **mangled
!= 'S')
4036 unsigned_const
= (**mangled
== 'U');
4043 string_append (result
, "-");
4049 /* special case for -2^31 */
4050 string_append (result
, "-2147483648");
4057 /* We have to be looking at an integer now */
4058 if (!(ISDIGIT ((unsigned char)**mangled
)))
4061 /* We only deal with integral values for template
4062 parameters -- so it's OK to look only for digits */
4063 while (ISDIGIT ((unsigned char)**mangled
))
4065 char_str
[0] = **mangled
;
4066 string_append (result
, char_str
);
4071 string_append (result
, "U");
4073 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4074 with L or LL suffixes. pai/1997-09-03 */
4076 return 1; /* success */
4079 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4080 **mangled is pointing to the 'A' */
4083 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
4086 int literal_len
= 0;
4090 if (**mangled
!= 'A')
4095 literal_len
= consume_count (mangled
);
4097 if (literal_len
<= 0)
4100 /* Literal parameters are names of arrays, functions, etc. and the
4101 canonical representation uses the address operator */
4102 string_append (result
, "&");
4104 /* Now recursively demangle the literal name */
4105 recurse
= XNEWVEC (char, literal_len
+ 1);
4106 memcpy (recurse
, *mangled
, literal_len
);
4107 recurse
[literal_len
] = '\000';
4109 recurse_dem
= cplus_demangle (recurse
, work
->options
);
4113 string_append (result
, recurse_dem
);
4118 string_appendn (result
, *mangled
, literal_len
);
4120 (*mangled
) += literal_len
;
4127 snarf_numeric_literal (const char **args
, string
*arg
)
4132 string_append (arg
, char_str
);
4135 else if (**args
== '+')
4138 if (!ISDIGIT ((unsigned char)**args
))
4141 while (ISDIGIT ((unsigned char)**args
))
4143 char_str
[0] = **args
;
4144 string_append (arg
, char_str
);
4151 /* Demangle the next argument, given by MANGLED into RESULT, which
4152 *should be an uninitialized* string. It will be initialized here,
4153 and free'd should anything go wrong. */
4156 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4158 /* Remember where we started so that we can record the type, for
4159 non-squangling type remembering. */
4160 const char *start
= *mangled
;
4162 string_init (result
);
4164 if (work
->nrepeats
> 0)
4168 if (work
->previous_argument
== 0)
4171 /* We want to reissue the previous type in this argument list. */
4172 string_appends (result
, work
->previous_argument
);
4176 if (**mangled
== 'n')
4178 /* A squangling-style repeat. */
4180 work
->nrepeats
= consume_count(mangled
);
4182 if (work
->nrepeats
<= 0)
4183 /* This was not a repeat count after all. */
4186 if (work
->nrepeats
> 9)
4188 if (**mangled
!= '_')
4189 /* The repeat count should be followed by an '_' in this
4196 /* Now, the repeat is all set up. */
4197 return do_arg (work
, mangled
, result
);
4200 /* Save the result in WORK->previous_argument so that we can find it
4201 if it's repeated. Note that saving START is not good enough: we
4202 do not want to add additional types to the back-referenceable
4203 type vector when processing a repeated type. */
4204 if (work
->previous_argument
)
4205 string_delete (work
->previous_argument
);
4207 work
->previous_argument
= XNEW (string
);
4209 if (!do_type (work
, mangled
, work
->previous_argument
))
4212 string_appends (result
, work
->previous_argument
);
4214 remember_type (work
, start
, *mangled
- start
);
4219 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4223 if (work
->forgetting_types
)
4226 if (work
-> ntypes
>= work
-> typevec_size
)
4228 if (work
-> typevec_size
== 0)
4230 work
-> typevec_size
= 3;
4231 work
-> typevec
= XNEWVEC (char *, work
->typevec_size
);
4235 work
-> typevec_size
*= 2;
4237 = XRESIZEVEC (char *, work
->typevec
, work
->typevec_size
);
4240 tem
= XNEWVEC (char, len
+ 1);
4241 memcpy (tem
, start
, len
);
4243 work
-> typevec
[work
-> ntypes
++] = tem
;
4247 /* Remember a K type class qualifier. */
4249 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4253 if (work
-> numk
>= work
-> ksize
)
4255 if (work
-> ksize
== 0)
4258 work
-> ktypevec
= XNEWVEC (char *, work
->ksize
);
4264 = XRESIZEVEC (char *, work
->ktypevec
, work
->ksize
);
4267 tem
= XNEWVEC (char, len
+ 1);
4268 memcpy (tem
, start
, len
);
4270 work
-> ktypevec
[work
-> numk
++] = tem
;
4273 /* Register a B code, and get an index for it. B codes are registered
4274 as they are seen, rather than as they are completed, so map<temp<char> >
4275 registers map<temp<char> > as B0, and temp<char> as B1 */
4278 register_Btype (struct work_stuff
*work
)
4282 if (work
-> numb
>= work
-> bsize
)
4284 if (work
-> bsize
== 0)
4287 work
-> btypevec
= XNEWVEC (char *, work
->bsize
);
4293 = XRESIZEVEC (char *, work
->btypevec
, work
->bsize
);
4296 ret
= work
-> numb
++;
4297 work
-> btypevec
[ret
] = NULL
;
4301 /* Store a value into a previously registered B code type. */
4304 remember_Btype (struct work_stuff
*work
, const char *start
,
4309 tem
= XNEWVEC (char, len
+ 1);
4310 memcpy (tem
, start
, len
);
4312 work
-> btypevec
[index
] = tem
;
4315 /* Lose all the info related to B and K type codes. */
4317 forget_B_and_K_types (struct work_stuff
*work
)
4321 while (work
-> numk
> 0)
4323 i
= --(work
-> numk
);
4324 if (work
-> ktypevec
[i
] != NULL
)
4326 free (work
-> ktypevec
[i
]);
4327 work
-> ktypevec
[i
] = NULL
;
4331 while (work
-> numb
> 0)
4333 i
= --(work
-> numb
);
4334 if (work
-> btypevec
[i
] != NULL
)
4336 free (work
-> btypevec
[i
]);
4337 work
-> btypevec
[i
] = NULL
;
4341 /* Forget the remembered types, but not the type vector itself. */
4344 forget_types (struct work_stuff
*work
)
4348 while (work
-> ntypes
> 0)
4350 i
= --(work
-> ntypes
);
4351 if (work
-> typevec
[i
] != NULL
)
4353 free (work
-> typevec
[i
]);
4354 work
-> typevec
[i
] = NULL
;
4359 /* Process the argument list part of the signature, after any class spec
4360 has been consumed, as well as the first 'F' character (if any). For
4363 "__als__3fooRT0" => process "RT0"
4364 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4366 DECLP must be already initialised, usually non-empty. It won't be freed
4369 Note that g++ differs significantly from ARM and lucid style mangling
4370 with regards to references to previously seen types. For example, given
4371 the source fragment:
4375 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4378 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4379 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4381 g++ produces the names:
4386 while lcc (and presumably other ARM style compilers as well) produces:
4388 foo__FiR3fooT1T2T1T2
4389 __ct__3fooFiR3fooT1T2T1T2
4391 Note that g++ bases its type numbers starting at zero and counts all
4392 previously seen types, while lucid/ARM bases its type numbers starting
4393 at one and only considers types after it has seen the 'F' character
4394 indicating the start of the function args. For lucid/ARM style, we
4395 account for this difference by discarding any previously seen types when
4396 we see the 'F' character, and subtracting one from the type number
4402 demangle_args (struct work_stuff
*work
, const char **mangled
,
4412 if (PRINT_ARG_TYPES
)
4414 string_append (declp
, "(");
4415 if (**mangled
== '\0')
4417 string_append (declp
, "void");
4421 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4422 || work
->nrepeats
> 0)
4424 if ((**mangled
== 'N') || (**mangled
== 'T'))
4426 temptype
= *(*mangled
)++;
4428 if (temptype
== 'N')
4430 if (!get_count (mangled
, &r
))
4439 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4441 /* If we have 10 or more types we might have more than a 1 digit
4442 index so we'll have to consume the whole count here. This
4443 will lose if the next thing is a type name preceded by a
4444 count but it's impossible to demangle that case properly
4445 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4446 Pc, ...)" or "(..., type12, char *, ...)" */
4447 if ((t
= consume_count(mangled
)) <= 0)
4454 if (!get_count (mangled
, &t
))
4459 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4463 /* Validate the type index. Protect against illegal indices from
4464 malformed type strings. */
4465 if ((t
< 0) || (t
>= work
-> ntypes
))
4469 while (work
->nrepeats
> 0 || --r
>= 0)
4471 tem
= work
-> typevec
[t
];
4472 if (need_comma
&& PRINT_ARG_TYPES
)
4474 string_append (declp
, ", ");
4476 if (!do_arg (work
, &tem
, &arg
))
4480 if (PRINT_ARG_TYPES
)
4482 string_appends (declp
, &arg
);
4484 string_delete (&arg
);
4490 if (need_comma
&& PRINT_ARG_TYPES
)
4491 string_append (declp
, ", ");
4492 if (!do_arg (work
, mangled
, &arg
))
4494 if (PRINT_ARG_TYPES
)
4495 string_appends (declp
, &arg
);
4496 string_delete (&arg
);
4501 if (**mangled
== 'e')
4504 if (PRINT_ARG_TYPES
)
4508 string_append (declp
, ",");
4510 string_append (declp
, "...");
4514 if (PRINT_ARG_TYPES
)
4516 string_append (declp
, ")");
4521 /* Like demangle_args, but for demangling the argument lists of function
4522 and method pointers or references, not top-level declarations. */
4525 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4528 string
* saved_previous_argument
;
4532 /* The G++ name-mangling algorithm does not remember types on nested
4533 argument lists, unless -fsquangling is used, and in that case the
4534 type vector updated by remember_type is not used. So, we turn
4535 off remembering of types here. */
4536 ++work
->forgetting_types
;
4538 /* For the repeat codes used with -fsquangling, we must keep track of
4539 the last argument. */
4540 saved_previous_argument
= work
->previous_argument
;
4541 saved_nrepeats
= work
->nrepeats
;
4542 work
->previous_argument
= 0;
4545 /* Actually demangle the arguments. */
4546 result
= demangle_args (work
, mangled
, declp
);
4548 /* Restore the previous_argument field. */
4549 if (work
->previous_argument
)
4551 string_delete (work
->previous_argument
);
4552 free ((char *) work
->previous_argument
);
4554 work
->previous_argument
= saved_previous_argument
;
4555 --work
->forgetting_types
;
4556 work
->nrepeats
= saved_nrepeats
;
4561 /* Returns 1 if a valid function name was found or 0 otherwise. */
4564 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4565 string
*declp
, const char *scan
)
4571 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4572 string_need (declp
, 1);
4573 *(declp
-> p
) = '\0';
4575 /* Consume the function name, including the "__" separating the name
4576 from the signature. We are guaranteed that SCAN points to the
4579 (*mangled
) = scan
+ 2;
4580 /* We may be looking at an instantiation of a template function:
4581 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4582 following _F marks the start of the function arguments. Handle
4583 the template arguments first. */
4585 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4587 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4588 /* This leaves MANGLED pointing to the 'F' marking func args */
4591 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4594 /* See if we have an ARM style constructor or destructor operator.
4595 If so, then just record it, clear the decl, and return.
4596 We can't build the actual constructor/destructor decl until later,
4597 when we recover the class name from the signature. */
4599 if (strcmp (declp
-> b
, "__ct") == 0)
4601 work
-> constructor
+= 1;
4602 string_clear (declp
);
4605 else if (strcmp (declp
-> b
, "__dt") == 0)
4607 work
-> destructor
+= 1;
4608 string_clear (declp
);
4613 if (declp
->p
- declp
->b
>= 3
4614 && declp
->b
[0] == 'o'
4615 && declp
->b
[1] == 'p'
4616 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4618 /* see if it's an assignment expression */
4619 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4620 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4622 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4624 int len
= declp
->p
- declp
->b
- 10;
4625 if ((int) strlen (optable
[i
].in
) == len
4626 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4628 string_clear (declp
);
4629 string_append (declp
, "operator");
4630 string_append (declp
, optable
[i
].out
);
4631 string_append (declp
, "=");
4638 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4640 int len
= declp
->p
- declp
->b
- 3;
4641 if ((int) strlen (optable
[i
].in
) == len
4642 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4644 string_clear (declp
);
4645 string_append (declp
, "operator");
4646 string_append (declp
, optable
[i
].out
);
4652 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4653 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4655 /* type conversion operator */
4657 if (do_type (work
, &tem
, &type
))
4659 string_clear (declp
);
4660 string_append (declp
, "operator ");
4661 string_appends (declp
, &type
);
4662 string_delete (&type
);
4665 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4666 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4669 /* type conversion operator. */
4671 if (do_type (work
, &tem
, &type
))
4673 string_clear (declp
);
4674 string_append (declp
, "operator ");
4675 string_appends (declp
, &type
);
4676 string_delete (&type
);
4679 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4680 && ISLOWER((unsigned char)declp
->b
[2])
4681 && ISLOWER((unsigned char)declp
->b
[3]))
4683 if (declp
->b
[4] == '\0')
4686 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4688 if (strlen (optable
[i
].in
) == 2
4689 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4691 string_clear (declp
);
4692 string_append (declp
, "operator");
4693 string_append (declp
, optable
[i
].out
);
4700 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4703 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4705 if (strlen (optable
[i
].in
) == 3
4706 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4708 string_clear (declp
);
4709 string_append (declp
, "operator");
4710 string_append (declp
, optable
[i
].out
);
4718 /* If a function name was obtained but it's not valid, we were not
4720 if (LEN_STRING (declp
) == 1 && declp
->b
[0] == '.')
4726 /* a mini string-handling package */
4729 string_need (string
*s
, int n
)
4739 s
->p
= s
->b
= XNEWVEC (char, n
);
4742 else if (s
->e
- s
->p
< n
)
4747 s
->b
= XRESIZEVEC (char, s
->b
, n
);
4754 string_delete (string
*s
)
4759 s
->b
= s
->e
= s
->p
= NULL
;
4764 string_init (string
*s
)
4766 s
->b
= s
->p
= s
->e
= NULL
;
4770 string_clear (string
*s
)
4778 string_empty (string
*s
)
4780 return (s
->b
== s
->p
);
4786 string_append (string
*p
, const char *s
)
4789 if (s
== NULL
|| *s
== '\0')
4793 memcpy (p
->p
, s
, n
);
4798 string_appends (string
*p
, string
*s
)
4806 memcpy (p
->p
, s
->b
, n
);
4812 string_appendn (string
*p
, const char *s
, int n
)
4817 memcpy (p
->p
, s
, n
);
4823 string_prepend (string
*p
, const char *s
)
4825 if (s
!= NULL
&& *s
!= '\0')
4827 string_prependn (p
, s
, strlen (s
));
4832 string_prepends (string
*p
, string
*s
)
4836 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4841 string_prependn (string
*p
, const char *s
, int n
)
4848 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4852 memcpy (p
->b
, s
, n
);
4858 string_append_template_idx (string
*s
, int idx
)
4860 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4861 sprintf(buf
, "T%d", idx
);
4862 string_append (s
, buf
);