1 /* Demangler for GNU C++
2 Copyright (C) 1989-2018 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 In addition to the permissions in the GNU Library General Public
14 License, the Free Software Foundation gives you unlimited permission
15 to link the compiled version of this file into combinations with other
16 programs, and to distribute those combinations without any restriction
17 coming from the use of this file. (The Library Public License
18 restrictions do apply in other respects; for example, they cover
19 modification of the file, and distribution when not linked into a
22 Libiberty is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Library General Public License for more details.
27 You should have received a copy of the GNU Library General Public
28 License along with libiberty; see the file COPYING.LIB. If
29 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
30 Boston, MA 02110-1301, USA. */
32 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
34 This file imports xmalloc and xrealloc, which are like malloc and
35 realloc except that they generate a fatal error if there is no
38 /* This file lives in both GCC and libiberty. When making changes, please
39 try not to break either. */
45 #include "safe-ctype.h"
47 #include <sys/types.h>
62 # define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */
66 #undef CURRENT_DEMANGLING_STYLE
67 #define CURRENT_DEMANGLING_STYLE work->options
69 #include "libiberty.h"
71 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
73 /* A value at least one greater than the maximum number of characters
74 that will be output when using the `%d' format with `printf'. */
75 #define INTBUF_SIZE 32
77 extern void fancy_abort (void) ATTRIBUTE_NORETURN
;
79 /* In order to allow a single demangler executable to demangle strings
80 using various common values of CPLUS_MARKER, as well as any specific
81 one set at compile time, we maintain a string containing all the
82 commonly used ones, and check to see if the marker we are looking for
83 is in that string. CPLUS_MARKER is usually '$' on systems where the
84 assembler can deal with that. Where the assembler can't, it's usually
85 '.' (but on many systems '.' is used for other things). We put the
86 current defined CPLUS_MARKER first (which defaults to '$'), followed
87 by the next most common value, followed by an explicit '$' in case
88 the value of CPLUS_MARKER is not '$'.
90 We could avoid this if we could just get g++ to tell us what the actual
91 cplus marker character is as part of the debug information, perhaps by
92 ensuring that it is the character that terminates the gcc<n>_compiled
93 marker symbol (FIXME). */
95 #if !defined (CPLUS_MARKER)
96 #define CPLUS_MARKER '$'
99 enum demangling_styles current_demangling_style
= auto_demangling
;
101 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
103 static char char_str
[2] = { '\000', '\000' };
106 set_cplus_marker_for_demangling (int ch
)
108 cplus_markers
[0] = ch
;
111 typedef struct string
/* Beware: these aren't required to be */
112 { /* '\0' terminated. */
113 char *b
; /* pointer to start of string */
114 char *p
; /* pointer after last character */
115 char *e
; /* pointer after end of allocated space */
118 /* Stuff that is shared between sub-routines.
119 Using a shared structure allows cplus_demangle to be reentrant. */
135 int static_type
; /* A static member function */
136 int temp_start
; /* index in demangled to start of template args */
137 int type_quals
; /* The type qualifiers. */
138 int dllimported
; /* Symbol imported from a PE DLL */
139 char **tmpl_argvec
; /* Template function arguments. */
140 int ntmpl_args
; /* The number of template function arguments. */
141 int forgetting_types
; /* Nonzero if we are not remembering the types
143 string
* previous_argument
; /* The last function argument demangled. */
144 int nrepeats
; /* The number of times to repeat the previous
146 int *proctypevec
; /* Indices of currently processed remembered typevecs. */
147 int proctypevec_size
;
151 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
152 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
154 static const struct optable
156 const char *const in
;
157 const char *const out
;
160 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
161 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
162 {"new", " new", 0}, /* old (1.91, and 1.x) */
163 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
164 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
165 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
166 {"as", "=", DMGL_ANSI
}, /* ansi */
167 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
168 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
169 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
170 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
171 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
172 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
173 {"plus", "+", 0}, /* old */
174 {"pl", "+", DMGL_ANSI
}, /* ansi */
175 {"apl", "+=", DMGL_ANSI
}, /* ansi */
176 {"minus", "-", 0}, /* old */
177 {"mi", "-", DMGL_ANSI
}, /* ansi */
178 {"ami", "-=", DMGL_ANSI
}, /* ansi */
179 {"mult", "*", 0}, /* old */
180 {"ml", "*", DMGL_ANSI
}, /* ansi */
181 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
182 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
183 {"convert", "+", 0}, /* old (unary +) */
184 {"negate", "-", 0}, /* old (unary -) */
185 {"trunc_mod", "%", 0}, /* old */
186 {"md", "%", DMGL_ANSI
}, /* ansi */
187 {"amd", "%=", DMGL_ANSI
}, /* ansi */
188 {"trunc_div", "/", 0}, /* old */
189 {"dv", "/", DMGL_ANSI
}, /* ansi */
190 {"adv", "/=", DMGL_ANSI
}, /* ansi */
191 {"truth_andif", "&&", 0}, /* old */
192 {"aa", "&&", DMGL_ANSI
}, /* ansi */
193 {"truth_orif", "||", 0}, /* old */
194 {"oo", "||", DMGL_ANSI
}, /* ansi */
195 {"truth_not", "!", 0}, /* old */
196 {"nt", "!", DMGL_ANSI
}, /* ansi */
197 {"postincrement","++", 0}, /* old */
198 {"pp", "++", DMGL_ANSI
}, /* ansi */
199 {"postdecrement","--", 0}, /* old */
200 {"mm", "--", DMGL_ANSI
}, /* ansi */
201 {"bit_ior", "|", 0}, /* old */
202 {"or", "|", DMGL_ANSI
}, /* ansi */
203 {"aor", "|=", DMGL_ANSI
}, /* ansi */
204 {"bit_xor", "^", 0}, /* old */
205 {"er", "^", DMGL_ANSI
}, /* ansi */
206 {"aer", "^=", DMGL_ANSI
}, /* ansi */
207 {"bit_and", "&", 0}, /* old */
208 {"ad", "&", DMGL_ANSI
}, /* ansi */
209 {"aad", "&=", DMGL_ANSI
}, /* ansi */
210 {"bit_not", "~", 0}, /* old */
211 {"co", "~", DMGL_ANSI
}, /* ansi */
212 {"call", "()", 0}, /* old */
213 {"cl", "()", DMGL_ANSI
}, /* ansi */
214 {"alshift", "<<", 0}, /* old */
215 {"ls", "<<", DMGL_ANSI
}, /* ansi */
216 {"als", "<<=", DMGL_ANSI
}, /* ansi */
217 {"arshift", ">>", 0}, /* old */
218 {"rs", ">>", DMGL_ANSI
}, /* ansi */
219 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
220 {"component", "->", 0}, /* old */
221 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
222 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
223 {"indirect", "*", 0}, /* old */
224 {"method_call", "->()", 0}, /* old */
225 {"addr", "&", 0}, /* old (unary &) */
226 {"array", "[]", 0}, /* old */
227 {"vc", "[]", DMGL_ANSI
}, /* ansi */
228 {"compound", ", ", 0}, /* old */
229 {"cm", ", ", DMGL_ANSI
}, /* ansi */
230 {"cond", "?:", 0}, /* old */
231 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
232 {"max", ">?", 0}, /* old */
233 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
234 {"min", "<?", 0}, /* old */
235 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
236 {"nop", "", 0}, /* old (for operator=) */
237 {"rm", "->*", DMGL_ANSI
}, /* ansi */
238 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
241 /* These values are used to indicate the various type varieties.
242 They are all non-zero so that they can be used as `success'
244 typedef enum type_kind_t
256 const struct demangler_engine libiberty_demanglers
[] =
259 NO_DEMANGLING_STYLE_STRING
,
261 "Demangling disabled"
265 AUTO_DEMANGLING_STYLE_STRING
,
267 "Automatic selection based on executable"
271 GNU_DEMANGLING_STYLE_STRING
,
273 "GNU (g++) style demangling"
277 LUCID_DEMANGLING_STYLE_STRING
,
279 "Lucid (lcc) style demangling"
283 ARM_DEMANGLING_STYLE_STRING
,
285 "ARM style demangling"
289 HP_DEMANGLING_STYLE_STRING
,
291 "HP (aCC) style demangling"
295 EDG_DEMANGLING_STYLE_STRING
,
297 "EDG style demangling"
301 GNU_V3_DEMANGLING_STYLE_STRING
,
303 "GNU (g++) V3 ABI-style demangling"
307 JAVA_DEMANGLING_STYLE_STRING
,
309 "Java style demangling"
313 GNAT_DEMANGLING_STYLE_STRING
,
315 "GNAT style demangling"
319 DLANG_DEMANGLING_STYLE_STRING
,
321 "DLANG style demangling"
325 RUST_DEMANGLING_STYLE_STRING
,
327 "Rust style demangling"
331 NULL
, unknown_demangling
, NULL
335 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
336 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
337 string_append(str, " ");}
338 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
340 /* The scope separator appropriate for the language being demangled. */
342 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
344 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
345 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
347 /* Prototypes for local functions */
349 static void delete_work_stuff (struct work_stuff
*);
351 static void delete_non_B_K_work_stuff (struct work_stuff
*);
353 static char *mop_up (struct work_stuff
*, string
*, int);
355 static void squangle_mop_up (struct work_stuff
*);
357 static void work_stuff_copy_to_from (struct work_stuff
*, struct work_stuff
*);
361 demangle_method_args (struct work_stuff
*, const char **, string
*);
365 internal_cplus_demangle (struct work_stuff
*, const char *);
368 demangle_template_template_parm (struct work_stuff
*work
,
369 const char **, string
*);
372 demangle_template (struct work_stuff
*work
, const char **, string
*,
376 arm_pt (struct work_stuff
*, const char *, int, const char **,
380 demangle_class_name (struct work_stuff
*, const char **, string
*);
383 demangle_qualified (struct work_stuff
*, const char **, string
*,
386 static int demangle_class (struct work_stuff
*, const char **, string
*);
388 static int demangle_fund_type (struct work_stuff
*, const char **, string
*);
390 static int demangle_signature (struct work_stuff
*, const char **, string
*);
392 static int demangle_prefix (struct work_stuff
*, const char **, string
*);
394 static int gnu_special (struct work_stuff
*, const char **, string
*);
396 static int arm_special (const char **, string
*);
398 static void string_need (string
*, int);
400 static void string_delete (string
*);
403 string_init (string
*);
405 static void string_clear (string
*);
408 static int string_empty (string
*);
411 static void string_append (string
*, const char *);
413 static void string_appends (string
*, string
*);
415 static void string_appendn (string
*, const char *, int);
417 static void string_prepend (string
*, const char *);
419 static void string_prependn (string
*, const char *, int);
421 static void string_append_template_idx (string
*, int);
423 static int get_count (const char **, int *);
425 static int consume_count (const char **);
427 static int consume_count_with_underscores (const char**);
429 static int demangle_args (struct work_stuff
*, const char **, string
*);
431 static int demangle_nested_args (struct work_stuff
*, const char**, string
*);
433 static int do_type (struct work_stuff
*, const char **, string
*);
435 static int do_arg (struct work_stuff
*, const char **, string
*);
438 demangle_function_name (struct work_stuff
*, const char **, string
*,
442 iterate_demangle_function (struct work_stuff
*,
443 const char **, string
*, const char *);
445 static void remember_type (struct work_stuff
*, const char *, int);
447 static void push_processed_type (struct work_stuff
*, int);
449 static void pop_processed_type (struct work_stuff
*);
451 static void remember_Btype (struct work_stuff
*, const char *, int, int);
453 static int register_Btype (struct work_stuff
*);
455 static void remember_Ktype (struct work_stuff
*, const char *, int);
457 static void forget_types (struct work_stuff
*);
459 static void forget_B_and_K_types (struct work_stuff
*);
461 static void string_prepends (string
*, string
*);
464 demangle_template_value_parm (struct work_stuff
*, const char**,
465 string
*, type_kind_t
);
468 do_hpacc_template_const_value (struct work_stuff
*, const char **, string
*);
471 do_hpacc_template_literal (struct work_stuff
*, const char **, string
*);
473 static int snarf_numeric_literal (const char **, string
*);
475 /* There is a TYPE_QUAL value for each type qualifier. They can be
476 combined by bitwise-or to form the complete set of qualifiers for a
479 #define TYPE_UNQUALIFIED 0x0
480 #define TYPE_QUAL_CONST 0x1
481 #define TYPE_QUAL_VOLATILE 0x2
482 #define TYPE_QUAL_RESTRICT 0x4
484 static int code_for_qualifier (int);
486 static const char* qualifier_string (int);
488 static const char* demangle_qualifier (int);
490 static int demangle_expression (struct work_stuff
*, const char **, string
*,
494 demangle_integral_value (struct work_stuff
*, const char **, string
*);
497 demangle_real_value (struct work_stuff
*, const char **, string
*);
500 demangle_arm_hp_template (struct work_stuff
*, const char **, int, string
*);
503 recursively_demangle (struct work_stuff
*, const char **, string
*, int);
505 /* Translate count to integer, consuming tokens in the process.
506 Conversion terminates on the first non-digit character.
508 Trying to consume something that isn't a count results in no
509 consumption of input and a return of -1.
511 Overflow consumes the rest of the digits, and returns -1. */
514 consume_count (const char **type
)
518 if (! ISDIGIT ((unsigned char)**type
))
521 while (ISDIGIT ((unsigned char)**type
))
523 const int digit
= **type
- '0';
524 /* Check for overflow. */
525 if (count
> ((INT_MAX
- digit
) / 10))
527 while (ISDIGIT ((unsigned char) **type
))
544 /* Like consume_count, but for counts that are preceded and followed
545 by '_' if they are greater than 10. Also, -1 is returned for
546 failure, since 0 can be a valid value. */
549 consume_count_with_underscores (const char **mangled
)
553 if (**mangled
== '_')
556 if (!ISDIGIT ((unsigned char)**mangled
))
559 idx
= consume_count (mangled
);
560 if (**mangled
!= '_')
561 /* The trailing underscore was missing. */
568 if (**mangled
< '0' || **mangled
> '9')
571 idx
= **mangled
- '0';
578 /* C is the code for a type-qualifier. Return the TYPE_QUAL
579 corresponding to this qualifier. */
582 code_for_qualifier (int c
)
587 return TYPE_QUAL_CONST
;
590 return TYPE_QUAL_VOLATILE
;
593 return TYPE_QUAL_RESTRICT
;
599 /* C was an invalid qualifier. */
603 /* Return the string corresponding to the qualifiers given by
607 qualifier_string (int type_quals
)
611 case TYPE_UNQUALIFIED
:
614 case TYPE_QUAL_CONST
:
617 case TYPE_QUAL_VOLATILE
:
620 case TYPE_QUAL_RESTRICT
:
623 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
624 return "const volatile";
626 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
627 return "const __restrict";
629 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
630 return "volatile __restrict";
632 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
633 return "const volatile __restrict";
639 /* TYPE_QUALS was an invalid qualifier set. */
643 /* C is the code for a type-qualifier. Return the string
644 corresponding to this qualifier. This function should only be
645 called with a valid qualifier code. */
648 demangle_qualifier (int c
)
650 return qualifier_string (code_for_qualifier (c
));
654 cplus_demangle_opname (const char *opname
, char *result
, int options
)
658 struct work_stuff work
[1];
661 len
= strlen(opname
);
664 memset ((char *) work
, 0, sizeof (work
));
665 work
->options
= options
;
667 if (opname
[0] == '_' && opname
[1] == '_'
668 && opname
[2] == 'o' && opname
[3] == 'p')
671 /* type conversion operator. */
673 if (do_type (work
, &tem
, &type
))
675 strcat (result
, "operator ");
676 strncat (result
, type
.b
, type
.p
- type
.b
);
677 string_delete (&type
);
681 else if (opname
[0] == '_' && opname
[1] == '_'
682 && ISLOWER((unsigned char)opname
[2])
683 && ISLOWER((unsigned char)opname
[3]))
685 if (opname
[4] == '\0')
689 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
691 if (strlen (optable
[i
].in
) == 2
692 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
694 strcat (result
, "operator");
695 strcat (result
, optable
[i
].out
);
703 if (opname
[2] == 'a' && opname
[5] == '\0')
707 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
709 if (strlen (optable
[i
].in
) == 3
710 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
712 strcat (result
, "operator");
713 strcat (result
, optable
[i
].out
);
724 && strchr (cplus_markers
, opname
[2]) != NULL
)
726 /* see if it's an assignment expression */
727 if (len
>= 10 /* op$assign_ */
728 && memcmp (opname
+ 3, "assign_", 7) == 0)
731 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
734 if ((int) strlen (optable
[i
].in
) == len1
735 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
737 strcat (result
, "operator");
738 strcat (result
, optable
[i
].out
);
739 strcat (result
, "=");
748 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
751 if ((int) strlen (optable
[i
].in
) == len1
752 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
754 strcat (result
, "operator");
755 strcat (result
, optable
[i
].out
);
762 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
763 && strchr (cplus_markers
, opname
[4]) != NULL
)
765 /* type conversion operator */
767 if (do_type (work
, &tem
, &type
))
769 strcat (result
, "operator ");
770 strncat (result
, type
.b
, type
.p
- type
.b
);
771 string_delete (&type
);
775 squangle_mop_up (work
);
780 /* Takes operator name as e.g. "++" and returns mangled
781 operator name (e.g. "postincrement_expr"), or NULL if not found.
783 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
784 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
787 cplus_mangle_opname (const char *opname
, int options
)
792 len
= strlen (opname
);
793 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
795 if ((int) strlen (optable
[i
].out
) == len
796 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
797 && memcmp (optable
[i
].out
, opname
, len
) == 0)
798 return optable
[i
].in
;
803 /* Add a routine to set the demangling style to be sure it is valid and
804 allow for any demangler initialization that maybe necessary. */
806 enum demangling_styles
807 cplus_demangle_set_style (enum demangling_styles style
)
809 const struct demangler_engine
*demangler
= libiberty_demanglers
;
811 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
812 if (style
== demangler
->demangling_style
)
814 current_demangling_style
= style
;
815 return current_demangling_style
;
818 return unknown_demangling
;
821 /* Do string name to style translation */
823 enum demangling_styles
824 cplus_demangle_name_to_style (const char *name
)
826 const struct demangler_engine
*demangler
= libiberty_demanglers
;
828 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
829 if (strcmp (name
, demangler
->demangling_style_name
) == 0)
830 return demangler
->demangling_style
;
832 return unknown_demangling
;
835 /* char *cplus_demangle (const char *mangled, int options)
837 If MANGLED is a mangled function name produced by GNU C++, then
838 a pointer to a @code{malloc}ed string giving a C++ representation
839 of the name will be returned; otherwise NULL will be returned.
840 It is the caller's responsibility to free the string which
843 The OPTIONS arg may contain one or more of the following bits:
845 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
847 DMGL_PARAMS Function parameters are included.
851 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
852 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
853 cplus_demangle ("foo__1Ai", 0) => "A::foo"
855 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
856 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
857 cplus_demangle ("foo__1Afe", 0) => "A::foo"
859 Note that any leading underscores, or other such characters prepended by
860 the compilation system, are presumed to have already been stripped from
864 cplus_demangle (const char *mangled
, int options
)
867 struct work_stuff work
[1];
869 if (current_demangling_style
== no_demangling
)
870 return xstrdup (mangled
);
872 memset ((char *) work
, 0, sizeof (work
));
873 work
->options
= options
;
874 if ((work
->options
& DMGL_STYLE_MASK
) == 0)
875 work
->options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
877 /* The V3 ABI demangling is implemented elsewhere. */
878 if (GNU_V3_DEMANGLING
|| RUST_DEMANGLING
|| AUTO_DEMANGLING
)
880 ret
= cplus_demangle_v3 (mangled
, work
->options
);
881 if (GNU_V3_DEMANGLING
)
886 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions.
887 The subtitutions are always smaller, so do in place changes. */
888 if (rust_is_mangled (ret
))
889 rust_demangle_sym (ret
);
890 else if (RUST_DEMANGLING
)
897 if (ret
|| RUST_DEMANGLING
)
903 ret
= java_demangle_v3 (mangled
);
909 return ada_demangle (mangled
, options
);
911 if (DLANG_DEMANGLING
)
913 ret
= dlang_demangle (mangled
, options
);
918 ret
= internal_cplus_demangle (work
, mangled
);
919 squangle_mop_up (work
);
924 rust_demangle (const char *mangled
, int options
)
926 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions. */
927 char *ret
= cplus_demangle_v3 (mangled
, options
);
929 /* The Rust subtitutions are always smaller, so do in place changes. */
932 if (rust_is_mangled (ret
))
933 rust_demangle_sym (ret
);
944 /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
947 ada_demangle (const char *mangled
, int option ATTRIBUTE_UNUSED
)
952 char *demangled
= NULL
;
954 /* Discard leading _ada_, which is used for library level subprograms. */
955 if (strncmp (mangled
, "_ada_", 5) == 0)
958 /* All ada unit names are lower-case. */
959 if (!ISLOWER (mangled
[0]))
962 /* Most of the demangling will trivially remove chars. Operator names
963 may add one char but because they are always preceeded by '__' which is
964 replaced by '.', they eventually never expand the size.
965 A few special names such as '___elabs' add a few chars (at most 7), but
966 they occur only once. */
967 len0
= strlen (mangled
) + 7 + 1;
968 demangled
= XNEWVEC (char, len0
);
974 /* An entity names is expected. */
977 /* An identifier, which is always lower case. */
980 while (ISLOWER(*p
) || ISDIGIT (*p
)
981 || (p
[0] == '_' && (ISLOWER (p
[1]) || ISDIGIT (p
[1]))));
983 else if (p
[0] == 'O')
985 /* An operator name. */
986 static const char * const operators
[][2] =
987 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
988 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
989 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
990 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
991 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
992 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
993 {"Oexpon", "**"}, {NULL
, NULL
}};
996 for (k
= 0; operators
[k
][0] != NULL
; k
++)
998 size_t slen
= strlen (operators
[k
][0]);
999 if (strncmp (p
, operators
[k
][0], slen
) == 0)
1002 slen
= strlen (operators
[k
][1]);
1004 memcpy (d
, operators
[k
][1], slen
);
1010 /* Operator not found. */
1011 if (operators
[k
][0] == NULL
)
1016 /* Not a GNAT encoding. */
1020 /* The name can be directly followed by some uppercase letters. */
1021 if (p
[0] == 'T' && p
[1] == 'K')
1024 if (p
[2] == 'B' && p
[3] == 0)
1026 /* Subprogram for task body. */
1029 else if (p
[2] == '_' && p
[3] == '_')
1031 /* Inner declarations in a task. */
1039 if (p
[0] == 'E' && p
[1] == 0)
1041 /* Exception name. */
1044 if ((p
[0] == 'P' || p
[0] == 'N') && p
[1] == 0)
1046 /* Protected type subprogram. */
1049 if ((*p
== 'N' || *p
== 'S') && p
[1] == 0)
1051 /* Enumerated type name table. */
1058 while (p
[0] == 'n' || p
[0] == 'b')
1061 if (p
[0] == 'S' && p
[1] != 0 && (p
[2] == '_' || p
[2] == 0))
1063 /* Stream operations. */
1086 else if (p
[0] == 'D')
1088 /* Controlled type operation. */
1111 /* Standard separator. Handled first. */
1116 /* Overloading number. */
1119 while (ISDIGIT (*p
) || (p
[0] == '_' && ISDIGIT (p
[1])));
1123 while (p
[0] == 'n' || p
[0] == 'b')
1127 else if (p
[0] == '_' && p
[1] != '_')
1129 /* Special names. */
1130 static const char * const special
[][2] = {
1131 { "_elabb", "'Elab_Body" },
1132 { "_elabs", "'Elab_Spec" },
1133 { "_size", "'Size" },
1134 { "_alignment", "'Alignment" },
1135 { "_assign", ".\":=\"" },
1140 for (k
= 0; special
[k
][0] != NULL
; k
++)
1142 size_t slen
= strlen (special
[k
][0]);
1143 if (strncmp (p
, special
[k
][0], slen
) == 0)
1146 slen
= strlen (special
[k
][1]);
1147 memcpy (d
, special
[k
][1], slen
);
1152 if (special
[k
][0] != NULL
)
1163 else if (p
[1] == 'B' || p
[1] == 'E')
1165 /* Entry Body or barrier Evaluation. */
1167 while (ISDIGIT (*p
))
1169 if (p
[0] == 's' && p
[1] == 0)
1178 if (p
[0] == '.' && ISDIGIT (p
[1]))
1180 /* Nested subprogram. */
1182 while (ISDIGIT (*p
))
1187 /* End of mangled name. */
1197 XDELETEVEC (demangled
);
1198 len0
= strlen (mangled
);
1199 demangled
= XNEWVEC (char, len0
+ 3);
1201 if (mangled
[0] == '<')
1202 strcpy (demangled
, mangled
);
1204 sprintf (demangled
, "<%s>", mangled
);
1209 /* This function performs most of what cplus_demangle use to do, but
1210 to be able to demangle a name with a B, K or n code, we need to
1211 have a longer term memory of what types have been seen. The original
1212 now initializes and cleans up the squangle code info, while internal
1213 calls go directly to this routine to avoid resetting that info. */
1216 internal_cplus_demangle (struct work_stuff
*work
, const char *mangled
)
1221 char *demangled
= NULL
;
1223 s1
= work
->constructor
;
1224 s2
= work
->destructor
;
1225 s3
= work
->static_type
;
1226 s4
= work
->type_quals
;
1227 work
->constructor
= work
->destructor
= 0;
1228 work
->type_quals
= TYPE_UNQUALIFIED
;
1229 work
->dllimported
= 0;
1231 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
1233 string_init (&decl
);
1235 /* First check to see if gnu style demangling is active and if the
1236 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1237 recognize one of the gnu special forms rather than looking for a
1238 standard prefix. In particular, don't worry about whether there
1239 is a "__" string in the mangled string. Consider "_$_5__foo" for
1242 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
1244 success
= gnu_special (work
, &mangled
, &decl
);
1247 delete_work_stuff (work
);
1248 string_delete (&decl
);
1253 success
= demangle_prefix (work
, &mangled
, &decl
);
1255 if (success
&& (*mangled
!= '\0'))
1257 success
= demangle_signature (work
, &mangled
, &decl
);
1259 if (work
->constructor
== 2)
1261 string_prepend (&decl
, "global constructors keyed to ");
1262 work
->constructor
= 0;
1264 else if (work
->destructor
== 2)
1266 string_prepend (&decl
, "global destructors keyed to ");
1267 work
->destructor
= 0;
1269 else if (work
->dllimported
== 1)
1271 string_prepend (&decl
, "import stub for ");
1272 work
->dllimported
= 0;
1274 demangled
= mop_up (work
, &decl
, success
);
1276 work
->constructor
= s1
;
1277 work
->destructor
= s2
;
1278 work
->static_type
= s3
;
1279 work
->type_quals
= s4
;
1284 /* Clear out and squangling related storage */
1286 squangle_mop_up (struct work_stuff
*work
)
1288 /* clean up the B and K type mangling types. */
1289 forget_B_and_K_types (work
);
1290 if (work
-> btypevec
!= NULL
)
1292 free ((char *) work
-> btypevec
);
1293 work
->btypevec
= NULL
;
1296 if (work
-> ktypevec
!= NULL
)
1298 free ((char *) work
-> ktypevec
);
1299 work
->ktypevec
= NULL
;
1305 /* Copy the work state and storage. */
1308 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1312 delete_work_stuff (to
);
1314 /* Shallow-copy scalars. */
1315 memcpy (to
, from
, sizeof (*to
));
1317 /* Deep-copy dynamic storage. */
1318 if (from
->typevec_size
)
1319 to
->typevec
= XNEWVEC (char *, from
->typevec_size
);
1321 for (i
= 0; i
< from
->ntypes
; i
++)
1323 int len
= strlen (from
->typevec
[i
]) + 1;
1325 to
->typevec
[i
] = XNEWVEC (char, len
);
1326 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1330 to
->ktypevec
= XNEWVEC (char *, from
->ksize
);
1332 for (i
= 0; i
< from
->numk
; i
++)
1334 int len
= strlen (from
->ktypevec
[i
]) + 1;
1336 to
->ktypevec
[i
] = XNEWVEC (char, len
);
1337 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1341 to
->btypevec
= XNEWVEC (char *, from
->bsize
);
1343 for (i
= 0; i
< from
->numb
; i
++)
1345 int len
= strlen (from
->btypevec
[i
]) + 1;
1347 to
->btypevec
[i
] = XNEWVEC (char , len
);
1348 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1351 if (from
->proctypevec
)
1353 XDUPVEC (int, from
->proctypevec
, from
->proctypevec_size
);
1355 if (from
->ntmpl_args
)
1356 to
->tmpl_argvec
= XNEWVEC (char *, from
->ntmpl_args
);
1358 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1360 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1362 to
->tmpl_argvec
[i
] = XNEWVEC (char, len
);
1363 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1366 if (from
->previous_argument
)
1368 to
->previous_argument
= XNEW (string
);
1369 string_init (to
->previous_argument
);
1370 string_appends (to
->previous_argument
, from
->previous_argument
);
1375 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1378 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1380 /* Discard the remembered types, if any. */
1382 forget_types (work
);
1383 if (work
->typevec
!= NULL
)
1385 free ((char *) work
->typevec
);
1386 work
->typevec
= NULL
;
1387 work
->typevec_size
= 0;
1389 if (work
->proctypevec
!= NULL
)
1391 free (work
->proctypevec
);
1392 work
->proctypevec
= NULL
;
1393 work
->proctypevec_size
= 0;
1395 if (work
->tmpl_argvec
)
1399 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1400 free ((char*) work
->tmpl_argvec
[i
]);
1402 free ((char*) work
->tmpl_argvec
);
1403 work
->tmpl_argvec
= NULL
;
1405 if (work
->previous_argument
)
1407 string_delete (work
->previous_argument
);
1408 free ((char*) work
->previous_argument
);
1409 work
->previous_argument
= NULL
;
1414 /* Delete all dynamic storage in work_stuff. */
1416 delete_work_stuff (struct work_stuff
*work
)
1418 delete_non_B_K_work_stuff (work
);
1419 squangle_mop_up (work
);
1423 /* Clear out any mangled storage */
1426 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1428 char *demangled
= NULL
;
1430 delete_non_B_K_work_stuff (work
);
1432 /* If demangling was successful, ensure that the demangled string is null
1433 terminated and return it. Otherwise, free the demangling decl. */
1437 string_delete (declp
);
1441 string_appendn (declp
, "", 1);
1442 demangled
= declp
->b
;
1451 demangle_signature -- demangle the signature part of a mangled name
1456 demangle_signature (struct work_stuff *work, const char **mangled,
1461 Consume and demangle the signature portion of the mangled name.
1463 DECLP is the string where demangled output is being built. At
1464 entry it contains the demangled root name from the mangled name
1465 prefix. I.E. either a demangled operator name or the root function
1466 name. In some special cases, it may contain nothing.
1468 *MANGLED points to the current unconsumed location in the mangled
1469 name. As tokens are consumed and demangling is performed, the
1470 pointer is updated to continuously point at the next token to
1473 Demangling GNU style mangled names is nasty because there is no
1474 explicit token that marks the start of the outermost function
1478 demangle_signature (struct work_stuff
*work
,
1479 const char **mangled
, string
*declp
)
1483 int expect_func
= 0;
1484 int expect_return_type
= 0;
1485 const char *oldmangled
= NULL
;
1489 while (success
&& (**mangled
!= '\0'))
1494 oldmangled
= *mangled
;
1495 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1497 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1498 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1504 oldmangled
= *mangled
;
1505 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1506 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1514 /* Static member function */
1515 if (oldmangled
== NULL
)
1517 oldmangled
= *mangled
;
1520 work
-> static_type
= 1;
1526 work
->type_quals
|= code_for_qualifier (**mangled
);
1528 /* a qualified member function */
1529 if (oldmangled
== NULL
)
1530 oldmangled
= *mangled
;
1535 /* Local class name follows after "Lnnn_" */
1538 while (**mangled
&& (**mangled
!= '_'))
1549 case '0': case '1': case '2': case '3': case '4':
1550 case '5': case '6': case '7': case '8': case '9':
1551 if (oldmangled
== NULL
)
1553 oldmangled
= *mangled
;
1555 work
->temp_start
= -1; /* uppermost call to demangle_class */
1556 success
= demangle_class (work
, mangled
, declp
);
1559 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1561 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1563 /* EDG and others will have the "F", so we let the loop cycle
1564 if we are looking at one. */
1565 if (**mangled
!= 'F')
1574 success
= do_type (work
, mangled
, &s
);
1577 string_append (&s
, SCOPE_STRING (work
));
1578 string_prepends (declp
, &s
);
1588 /* ARM/HP style demangling includes a specific 'F' character after
1589 the class name. For GNU style, it is just implied. So we can
1590 safely just consume any 'F' at this point and be compatible
1591 with either style. */
1597 /* For lucid/ARM/HP style we have to forget any types we might
1598 have remembered up to this point, since they were not argument
1599 types. GNU style considers all types seen as available for
1600 back references. See comment in demangle_args() */
1602 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1604 forget_types (work
);
1606 success
= demangle_args (work
, mangled
, declp
);
1607 /* After picking off the function args, we expect to either
1608 find the function return type (preceded by an '_') or the
1609 end of the string. */
1610 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1613 /* At this level, we do not care about the return type. */
1614 success
= do_type (work
, mangled
, &tname
);
1615 string_delete (&tname
);
1622 string_init(&trawname
);
1623 string_init(&tname
);
1624 if (oldmangled
== NULL
)
1626 oldmangled
= *mangled
;
1628 success
= demangle_template (work
, mangled
, &tname
,
1632 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1634 string_append (&tname
, SCOPE_STRING (work
));
1636 string_prepends(declp
, &tname
);
1637 if (work
-> destructor
& 1)
1639 string_prepend (&trawname
, "~");
1640 string_appends (declp
, &trawname
);
1641 work
->destructor
-= 1;
1643 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1645 string_appends (declp
, &trawname
);
1646 work
->constructor
-= 1;
1648 string_delete(&trawname
);
1649 string_delete(&tname
);
1655 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1657 /* Read the return type. */
1661 success
= do_type (work
, mangled
, &return_type
);
1662 APPEND_BLANK (&return_type
);
1664 string_prepends (declp
, &return_type
);
1665 string_delete (&return_type
);
1669 /* At the outermost level, we cannot have a return type specified,
1670 so if we run into another '_' at this point we are dealing with
1671 a mangled name that is either bogus, or has been mangled by
1672 some algorithm we don't know how to deal with. So just
1673 reject the entire demangling. */
1674 /* However, "_nnn" is an expected suffix for alternate entry point
1675 numbered nnn for a function, with HP aCC, so skip over that
1676 without reporting failure. pai/1997-09-04 */
1680 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1688 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1690 /* A G++ template function. Read the template arguments. */
1691 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1693 if (!(work
->constructor
& 1))
1694 expect_return_type
= 1;
1704 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1706 /* Assume we have stumbled onto the first outermost function
1707 argument token, and start processing args. */
1709 success
= demangle_args (work
, mangled
, declp
);
1713 /* Non-GNU demanglers use a specific token to mark the start
1714 of the outermost function argument tokens. Typically 'F',
1715 for ARM/HP-demangling, for example. So if we find something
1716 we are not prepared for, it must be an error. */
1722 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1725 if (success
&& expect_func
)
1728 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1730 forget_types (work
);
1732 success
= demangle_args (work
, mangled
, declp
);
1733 /* Since template include the mangling of their return types,
1734 we must set expect_func to 0 so that we don't try do
1735 demangle more arguments the next time we get here. */
1740 if (success
&& !func_done
)
1742 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1744 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1745 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1746 first case, and need to ensure that the '(void)' gets added to
1747 the current declp. Note that with ARM/HP, the first case
1748 represents the name of a static data member 'foo::bar',
1749 which is in the current declp, so we leave it alone. */
1750 success
= demangle_args (work
, mangled
, declp
);
1753 if (success
&& PRINT_ARG_TYPES
)
1755 if (work
->static_type
)
1756 string_append (declp
, " static");
1757 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1759 APPEND_BLANK (declp
);
1760 string_append (declp
, qualifier_string (work
->type_quals
));
1770 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1775 if (work
-> static_type
)
1777 string_append (declp
, *mangled
+ 1);
1778 *mangled
+= strlen (*mangled
);
1783 success
= demangle_args (work
, mangled
, declp
);
1791 demangle_template_template_parm (struct work_stuff
*work
,
1792 const char **mangled
, string
*tname
)
1800 string_append (tname
, "template <");
1801 /* get size of template parameter list */
1802 if (get_count (mangled
, &r
))
1804 for (i
= 0; i
< r
; i
++)
1808 string_append (tname
, ", ");
1811 /* Z for type parameters */
1812 if (**mangled
== 'Z')
1815 string_append (tname
, "class");
1817 /* z for template parameters */
1818 else if (**mangled
== 'z')
1822 demangle_template_template_parm (work
, mangled
, tname
);
1830 /* temp is initialized in do_type */
1831 success
= do_type (work
, mangled
, &temp
);
1834 string_appends (tname
, &temp
);
1836 string_delete(&temp
);
1846 if (tname
->p
[-1] == '>')
1847 string_append (tname
, " ");
1848 string_append (tname
, "> class");
1853 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1854 string
*s
, type_kind_t tk
)
1856 int need_operator
= 0;
1860 string_appendn (s
, "(", 1);
1862 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1871 len
= strlen (*mangled
);
1873 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1875 size_t l
= strlen (optable
[i
].in
);
1878 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1880 string_appendn (s
, " ", 1);
1881 string_append (s
, optable
[i
].out
);
1882 string_appendn (s
, " ", 1);
1895 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1898 if (**mangled
!= 'W')
1902 string_appendn (s
, ")", 1);
1910 demangle_integral_value (struct work_stuff
*work
,
1911 const char **mangled
, string
*s
)
1915 if (**mangled
== 'E')
1916 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1917 else if (**mangled
== 'Q' || **mangled
== 'K')
1918 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1923 /* By default, we let the number decide whether we shall consume an
1925 int multidigit_without_leading_underscore
= 0;
1926 int leave_following_underscore
= 0;
1930 if (**mangled
== '_')
1932 if (mangled
[0][1] == 'm')
1934 /* Since consume_count_with_underscores does not handle the
1935 `m'-prefix we must do it here, using consume_count and
1936 adjusting underscores: we have to consume the underscore
1937 matching the prepended one. */
1938 multidigit_without_leading_underscore
= 1;
1939 string_appendn (s
, "-", 1);
1944 /* Do not consume a following underscore;
1945 consume_count_with_underscores will consume what
1946 should be consumed. */
1947 leave_following_underscore
= 1;
1952 /* Negative numbers are indicated with a leading `m'. */
1953 if (**mangled
== 'm')
1955 string_appendn (s
, "-", 1);
1958 /* Since consume_count_with_underscores does not handle
1959 multi-digit numbers that do not start with an underscore,
1960 and this number can be an integer template parameter,
1961 we have to call consume_count. */
1962 multidigit_without_leading_underscore
= 1;
1963 /* These multi-digit numbers never end on an underscore,
1964 so if there is one then don't eat it. */
1965 leave_following_underscore
= 1;
1968 /* We must call consume_count if we expect to remove a trailing
1969 underscore, since consume_count_with_underscores expects
1970 the leading underscore (that we consumed) if it is to handle
1971 multi-digit numbers. */
1972 if (multidigit_without_leading_underscore
)
1973 value
= consume_count (mangled
);
1975 value
= consume_count_with_underscores (mangled
);
1979 char buf
[INTBUF_SIZE
];
1980 sprintf (buf
, "%d", value
);
1981 string_append (s
, buf
);
1983 /* Numbers not otherwise delimited, might have an underscore
1984 appended as a delimeter, which we should skip.
1986 ??? This used to always remove a following underscore, which
1987 is wrong. If other (arbitrary) cases are followed by an
1988 underscore, we need to do something more radical. */
1990 if ((value
> 9 || multidigit_without_leading_underscore
)
1991 && ! leave_following_underscore
1992 && **mangled
== '_')
2003 /* Demangle the real value in MANGLED. */
2006 demangle_real_value (struct work_stuff
*work
,
2007 const char **mangled
, string
*s
)
2009 if (**mangled
== 'E')
2010 return demangle_expression (work
, mangled
, s
, tk_real
);
2012 if (**mangled
== 'm')
2014 string_appendn (s
, "-", 1);
2017 while (ISDIGIT ((unsigned char)**mangled
))
2019 string_appendn (s
, *mangled
, 1);
2022 if (**mangled
== '.') /* fraction */
2024 string_appendn (s
, ".", 1);
2026 while (ISDIGIT ((unsigned char)**mangled
))
2028 string_appendn (s
, *mangled
, 1);
2032 if (**mangled
== 'e') /* exponent */
2034 string_appendn (s
, "e", 1);
2036 while (ISDIGIT ((unsigned char)**mangled
))
2038 string_appendn (s
, *mangled
, 1);
2047 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
2048 string
*s
, type_kind_t tk
)
2052 if (**mangled
== 'Y')
2054 /* The next argument is a template parameter. */
2058 idx
= consume_count_with_underscores (mangled
);
2060 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2061 || consume_count_with_underscores (mangled
) == -1)
2063 if (work
->tmpl_argvec
)
2064 string_append (s
, work
->tmpl_argvec
[idx
]);
2066 string_append_template_idx (s
, idx
);
2068 else if (tk
== tk_integral
)
2069 success
= demangle_integral_value (work
, mangled
, s
);
2070 else if (tk
== tk_char
)
2074 if (**mangled
== 'm')
2076 string_appendn (s
, "-", 1);
2079 string_appendn (s
, "'", 1);
2080 val
= consume_count(mangled
);
2087 string_appendn (s
, &tmp
[0], 1);
2088 string_appendn (s
, "'", 1);
2091 else if (tk
== tk_bool
)
2093 int val
= consume_count (mangled
);
2095 string_appendn (s
, "false", 5);
2097 string_appendn (s
, "true", 4);
2101 else if (tk
== tk_real
)
2102 success
= demangle_real_value (work
, mangled
, s
);
2103 else if (tk
== tk_pointer
|| tk
== tk_reference
2104 || tk
== tk_rvalue_reference
)
2106 if (**mangled
== 'Q')
2107 success
= demangle_qualified (work
, mangled
, s
,
2112 int symbol_len
= consume_count (mangled
);
2113 if (symbol_len
== -1
2114 || symbol_len
> (long) strlen (*mangled
))
2116 if (symbol_len
== 0)
2117 string_appendn (s
, "0", 1);
2120 char *p
= XNEWVEC (char, symbol_len
+ 1), *q
;
2121 strncpy (p
, *mangled
, symbol_len
);
2122 p
[symbol_len
] = '\0';
2123 /* We use cplus_demangle here, rather than
2124 internal_cplus_demangle, because the name of the entity
2125 mangled here does not make use of any of the squangling
2126 or type-code information we have built up thus far; it is
2127 mangled independently. */
2128 q
= cplus_demangle (p
, work
->options
);
2129 if (tk
== tk_pointer
)
2130 string_appendn (s
, "&", 1);
2131 /* FIXME: Pointer-to-member constants should get a
2132 qualifying class name here. */
2135 string_append (s
, q
);
2139 string_append (s
, p
);
2142 *mangled
+= symbol_len
;
2149 /* Demangle the template name in MANGLED. The full name of the
2150 template (e.g., S<int>) is placed in TNAME. The name without the
2151 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2152 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2153 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2154 the template is remembered in the list of back-referenceable
2158 demangle_template (struct work_stuff
*work
, const char **mangled
,
2159 string
*tname
, string
*trawname
,
2160 int is_type
, int remember
)
2166 int is_java_array
= 0;
2172 /* get template name */
2173 if (**mangled
== 'z')
2177 if (**mangled
== '\0')
2181 idx
= consume_count_with_underscores (mangled
);
2183 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2184 || consume_count_with_underscores (mangled
) == -1)
2187 if (work
->tmpl_argvec
)
2189 string_append (tname
, work
->tmpl_argvec
[idx
]);
2191 string_append (trawname
, work
->tmpl_argvec
[idx
]);
2195 string_append_template_idx (tname
, idx
);
2197 string_append_template_idx (trawname
, idx
);
2202 if ((r
= consume_count (mangled
)) <= 0
2203 || (int) strlen (*mangled
) < r
)
2207 is_java_array
= (work
-> options
& DMGL_JAVA
)
2208 && strncmp (*mangled
, "JArray1Z", 8) == 0;
2209 if (! is_java_array
)
2211 string_appendn (tname
, *mangled
, r
);
2214 string_appendn (trawname
, *mangled
, r
);
2219 string_append (tname
, "<");
2220 /* get size of template parameter list */
2221 if (!get_count (mangled
, &r
))
2227 /* Create an array for saving the template argument values. */
2228 work
->tmpl_argvec
= XNEWVEC (char *, r
);
2229 work
->ntmpl_args
= r
;
2230 for (i
= 0; i
< r
; i
++)
2231 work
->tmpl_argvec
[i
] = 0;
2233 for (i
= 0; i
< r
; i
++)
2237 string_append (tname
, ", ");
2239 /* Z for type parameters */
2240 if (**mangled
== 'Z')
2243 /* temp is initialized in do_type */
2244 success
= do_type (work
, mangled
, &temp
);
2247 string_appends (tname
, &temp
);
2251 /* Save the template argument. */
2252 int len
= temp
.p
- temp
.b
;
2253 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2254 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2255 work
->tmpl_argvec
[i
][len
] = '\0';
2258 string_delete(&temp
);
2264 /* z for template parameters */
2265 else if (**mangled
== 'z')
2269 success
= demangle_template_template_parm (work
, mangled
, tname
);
2272 && (r2
= consume_count (mangled
)) > 0
2273 && (int) strlen (*mangled
) >= r2
)
2275 string_append (tname
, " ");
2276 string_appendn (tname
, *mangled
, r2
);
2279 /* Save the template argument. */
2281 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2282 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2283 work
->tmpl_argvec
[i
][len
] = '\0';
2297 /* otherwise, value parameter */
2299 /* temp is initialized in do_type */
2300 success
= do_type (work
, mangled
, &temp
);
2301 string_delete(&temp
);
2313 success
= demangle_template_value_parm (work
, mangled
, s
,
2314 (type_kind_t
) success
);
2326 int len
= s
->p
- s
->b
;
2327 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2328 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2329 work
->tmpl_argvec
[i
][len
] = '\0';
2331 string_appends (tname
, s
);
2339 string_append (tname
, "[]");
2343 if (tname
->p
[-1] == '>')
2344 string_append (tname
, " ");
2345 string_append (tname
, ">");
2348 if (is_type
&& remember
)
2350 const int bindex
= register_Btype (work
);
2351 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2355 if (work -> static_type)
2357 string_append (declp, *mangled + 1);
2358 *mangled += strlen (*mangled);
2363 success = demangle_args (work, mangled, declp);
2371 arm_pt (struct work_stuff
*work
, const char *mangled
,
2372 int n
, const char **anchor
, const char **args
)
2374 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2375 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2376 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2379 *args
= *anchor
+ 6;
2380 len
= consume_count (args
);
2383 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2389 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2391 if ((*anchor
= strstr (mangled
, "__tm__"))
2392 || (*anchor
= strstr (mangled
, "__ps__"))
2393 || (*anchor
= strstr (mangled
, "__pt__")))
2396 *args
= *anchor
+ 6;
2397 len
= consume_count (args
);
2400 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2406 else if ((*anchor
= strstr (mangled
, "__S")))
2409 *args
= *anchor
+ 3;
2410 len
= consume_count (args
);
2413 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2425 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2426 int n
, string
*declp
)
2430 const char *e
= *mangled
+ n
;
2433 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2435 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2437 char *start_spec_args
= NULL
;
2440 /* First check for and omit template specialization pseudo-arguments,
2441 such as in "Spec<#1,#1.*>" */
2442 start_spec_args
= strchr (*mangled
, '<');
2443 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2444 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2446 string_appendn (declp
, *mangled
, n
);
2447 (*mangled
) += n
+ 1;
2449 if (work
->temp_start
== -1) /* non-recursive call */
2450 work
->temp_start
= declp
->p
- declp
->b
;
2452 /* We want to unconditionally demangle parameter types in
2453 template parameters. */
2454 hold_options
= work
->options
;
2455 work
->options
|= DMGL_PARAMS
;
2457 string_append (declp
, "<");
2460 string_delete (&arg
);
2464 /* 'T' signals a type parameter */
2466 if (!do_type (work
, mangled
, &arg
))
2467 goto hpacc_template_args_done
;
2472 /* 'U' or 'S' signals an integral value */
2473 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2474 goto hpacc_template_args_done
;
2478 /* 'A' signals a named constant expression (literal) */
2479 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2480 goto hpacc_template_args_done
;
2484 /* Today, 1997-09-03, we have only the above types
2485 of template parameters */
2486 /* FIXME: maybe this should fail and return null */
2487 goto hpacc_template_args_done
;
2489 string_appends (declp
, &arg
);
2490 /* Check if we're at the end of template args.
2491 0 if at end of static member of template class,
2492 _ if done with template args for a function */
2493 if ((**mangled
== '\000') || (**mangled
== '_'))
2496 string_append (declp
, ",");
2498 hpacc_template_args_done
:
2499 string_append (declp
, ">");
2500 string_delete (&arg
);
2501 if (**mangled
== '_')
2503 work
->options
= hold_options
;
2506 /* ARM template? (Also handles HP cfront extensions) */
2507 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2513 string_appendn (declp
, *mangled
, p
- *mangled
);
2514 if (work
->temp_start
== -1) /* non-recursive call */
2515 work
->temp_start
= declp
->p
- declp
->b
;
2517 /* We want to unconditionally demangle parameter types in
2518 template parameters. */
2519 hold_options
= work
->options
;
2520 work
->options
|= DMGL_PARAMS
;
2522 string_append (declp
, "<");
2523 /* should do error checking here */
2525 string_delete (&arg
);
2527 /* Check for type or literal here */
2530 /* HP cfront extensions to ARM for template args */
2531 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2532 /* FIXME: We handle only numeric literals for HP cfront */
2534 /* A typed constant value follows */
2536 if (!do_type (work
, &args
, &type_str
))
2537 goto cfront_template_args_done
;
2538 string_append (&arg
, "(");
2539 string_appends (&arg
, &type_str
);
2540 string_delete (&type_str
);
2541 string_append (&arg
, ")");
2543 goto cfront_template_args_done
;
2545 /* Now snarf a literal value following 'L' */
2546 if (!snarf_numeric_literal (&args
, &arg
))
2547 goto cfront_template_args_done
;
2551 /* Snarf a literal following 'L' */
2553 if (!snarf_numeric_literal (&args
, &arg
))
2554 goto cfront_template_args_done
;
2557 /* Not handling other HP cfront stuff */
2559 const char* old_args
= args
;
2560 if (!do_type (work
, &args
, &arg
))
2561 goto cfront_template_args_done
;
2563 /* Fail if we didn't make any progress: prevent infinite loop. */
2564 if (args
== old_args
)
2566 work
->options
= hold_options
;
2571 string_appends (declp
, &arg
);
2572 string_append (declp
, ",");
2574 cfront_template_args_done
:
2575 string_delete (&arg
);
2577 --declp
->p
; /* remove extra comma */
2578 string_append (declp
, ">");
2579 work
->options
= hold_options
;
2581 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2582 && (*mangled
)[9] == 'N'
2583 && (*mangled
)[8] == (*mangled
)[10]
2584 && strchr (cplus_markers
, (*mangled
)[8]))
2586 /* A member of the anonymous namespace. */
2587 string_append (declp
, "{anonymous}");
2591 if (work
->temp_start
== -1) /* non-recursive call only */
2592 work
->temp_start
= 0; /* disable in recursive calls */
2593 string_appendn (declp
, *mangled
, n
);
2598 /* Extract a class name, possibly a template with arguments, from the
2599 mangled string; qualifiers, local class indicators, etc. have
2600 already been dealt with */
2603 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2609 n
= consume_count (mangled
);
2612 if ((int) strlen (*mangled
) >= n
)
2614 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2625 demangle_class -- demangle a mangled class sequence
2630 demangle_class (struct work_stuff *work, const char **mangled,
2635 DECLP points to the buffer into which demangling is being done.
2637 *MANGLED points to the current token to be demangled. On input,
2638 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2639 On exit, it points to the next token after the mangled class on
2640 success, or the first unconsumed token on failure.
2642 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2643 we are demangling a constructor or destructor. In this case
2644 we prepend "class::class" or "class::~class" to DECLP.
2646 Otherwise, we prepend "class::" to the current DECLP.
2648 Reset the constructor/destructor flags once they have been
2649 "consumed". This allows demangle_class to be called later during
2650 the same demangling, to do normal class demangling.
2652 Returns 1 if demangling is successful, 0 otherwise.
2657 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2662 char *save_class_name_end
= 0;
2664 string_init (&class_name
);
2665 btype
= register_Btype (work
);
2666 if (demangle_class_name (work
, mangled
, &class_name
))
2668 save_class_name_end
= class_name
.p
;
2669 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2671 /* adjust so we don't include template args */
2672 if (work
->temp_start
&& (work
->temp_start
!= -1))
2674 class_name
.p
= class_name
.b
+ work
->temp_start
;
2676 string_prepends (declp
, &class_name
);
2677 if (work
-> destructor
& 1)
2679 string_prepend (declp
, "~");
2680 work
-> destructor
-= 1;
2684 work
-> constructor
-= 1;
2687 class_name
.p
= save_class_name_end
;
2688 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2689 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2690 string_prepend (declp
, SCOPE_STRING (work
));
2691 string_prepends (declp
, &class_name
);
2694 string_delete (&class_name
);
2699 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2700 the rightmost guess.
2702 Find the correct "__"-sequence where the function name ends and the
2703 signature starts, which is ambiguous with GNU mangling.
2704 Call demangle_signature here, so we can make sure we found the right
2705 one; *mangled will be consumed so caller will not make further calls to
2706 demangle_signature. */
2709 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2710 string
*declp
, const char *scan
)
2712 const char *mangle_init
= *mangled
;
2715 struct work_stuff work_init
;
2717 if (*(scan
+ 2) == '\0')
2720 /* Do not iterate for some demangling modes, or if there's only one
2721 "__"-sequence. This is the normal case. */
2722 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2723 || strstr (scan
+ 2, "__") == NULL
)
2724 return demangle_function_name (work
, mangled
, declp
, scan
);
2726 /* Save state so we can restart if the guess at the correct "__" was
2728 string_init (&decl_init
);
2729 string_appends (&decl_init
, declp
);
2730 memset (&work_init
, 0, sizeof work_init
);
2731 work_stuff_copy_to_from (&work_init
, work
);
2733 /* Iterate over occurrences of __, allowing names and types to have a
2734 "__" sequence in them. We must start with the first (not the last)
2735 occurrence, since "__" most often occur between independent mangled
2736 parts, hence starting at the last occurence inside a signature
2737 might get us a "successful" demangling of the signature. */
2741 if (demangle_function_name (work
, mangled
, declp
, scan
))
2743 success
= demangle_signature (work
, mangled
, declp
);
2748 /* Reset demangle state for the next round. */
2749 *mangled
= mangle_init
;
2750 string_clear (declp
);
2751 string_appends (declp
, &decl_init
);
2752 work_stuff_copy_to_from (work
, &work_init
);
2754 /* Leave this underscore-sequence. */
2757 /* Scan for the next "__" sequence. */
2758 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2761 /* Move to last "__" in this sequence. */
2762 while (*scan
&& *scan
== '_')
2767 /* Delete saved state. */
2768 delete_work_stuff (&work_init
);
2769 string_delete (&decl_init
);
2778 demangle_prefix -- consume the mangled name prefix and find signature
2783 demangle_prefix (struct work_stuff *work, const char **mangled,
2788 Consume and demangle the prefix of the mangled name.
2789 While processing the function name root, arrange to call
2790 demangle_signature if the root is ambiguous.
2792 DECLP points to the string buffer into which demangled output is
2793 placed. On entry, the buffer is empty. On exit it contains
2794 the root function name, the demangled operator name, or in some
2795 special cases either nothing or the completely demangled result.
2797 MANGLED points to the current pointer into the mangled name. As each
2798 token of the mangled name is consumed, it is updated. Upon entry
2799 the current mangled name pointer points to the first character of
2800 the mangled name. Upon exit, it should point to the first character
2801 of the signature if demangling was successful, or to the first
2802 unconsumed character if demangling of the prefix was unsuccessful.
2804 Returns 1 on success, 0 otherwise.
2808 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2815 if (strlen(*mangled
) > 6
2816 && (strncmp(*mangled
, "_imp__", 6) == 0
2817 || strncmp(*mangled
, "__imp_", 6) == 0))
2819 /* it's a symbol imported from a PE dynamic library. Check for both
2820 new style prefix _imp__ and legacy __imp_ used by older versions
2823 work
->dllimported
= 1;
2825 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2827 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2828 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2830 if ((*mangled
)[9] == 'D')
2832 /* it's a GNU global destructor to be executed at program exit */
2834 work
->destructor
= 2;
2835 if (gnu_special (work
, mangled
, declp
))
2838 else if ((*mangled
)[9] == 'I')
2840 /* it's a GNU global constructor to be executed at program init */
2842 work
->constructor
= 2;
2843 if (gnu_special (work
, mangled
, declp
))
2848 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2850 /* it's a ARM global destructor to be executed at program exit */
2852 work
->destructor
= 2;
2854 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2856 /* it's a ARM global constructor to be executed at program initial */
2858 work
->constructor
= 2;
2861 /* This block of code is a reduction in strength time optimization
2863 scan = strstr (*mangled, "__"); */
2869 scan
= strchr (scan
, '_');
2870 } while (scan
!= NULL
&& *++scan
!= '_');
2872 if (scan
!= NULL
) --scan
;
2877 /* We found a sequence of two or more '_', ensure that we start at
2878 the last pair in the sequence. */
2879 i
= strspn (scan
, "_");
2890 else if (work
-> static_type
)
2892 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2897 else if ((scan
== *mangled
)
2898 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2899 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2901 /* The ARM says nothing about the mangling of local variables.
2902 But cfront mangles local variables by prepending __<nesting_level>
2903 to them. As an extension to ARM demangling we handle this case. */
2904 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2905 && ISDIGIT ((unsigned char)scan
[2]))
2907 *mangled
= scan
+ 2;
2908 consume_count (mangled
);
2909 string_append (declp
, *mangled
);
2910 *mangled
+= strlen (*mangled
);
2915 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2916 names like __Q2_3foo3bar for nested type names. So don't accept
2917 this style of constructor for cfront demangling. A GNU
2918 style member-template constructor starts with 'H'. */
2919 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2920 work
-> constructor
+= 1;
2921 *mangled
= scan
+ 2;
2924 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2926 /* Cfront-style parameterized type. Handled later as a signature. */
2930 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2932 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2933 || (scan
[2] == 'p' && scan
[3] == 's')
2934 || (scan
[2] == 'p' && scan
[3] == 't')))
2936 /* EDG-style parameterized type. Handled later as a signature. */
2940 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2942 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2943 && (scan
[2] != 't'))
2945 /* Mangled name starts with "__". Skip over any leading '_' characters,
2946 then find the next "__" that separates the prefix from the signature.
2948 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2949 || (arm_special (mangled
, declp
) == 0))
2951 while (*scan
== '_')
2955 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2957 /* No separator (I.E. "__not_mangled"), or empty signature
2958 (I.E. "__not_mangled_either__") */
2962 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2965 else if (*(scan
+ 2) != '\0')
2967 /* Mangled name does not start with "__" but does have one somewhere
2968 in there with non empty stuff after it. Looks like a global
2969 function name. Iterate over all "__":s until the right
2971 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2975 /* Doesn't look like a mangled name */
2979 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2981 string_append (declp
, *mangled
);
2982 *mangled
+= strlen (*mangled
);
2992 gnu_special -- special handling of gnu mangled strings
2997 gnu_special (struct work_stuff *work, const char **mangled,
3003 Process some special GNU style mangling forms that don't fit
3004 the normal pattern. For example:
3006 _$_3foo (destructor for class foo)
3007 _vt$foo (foo virtual table)
3008 _vt$foo$bar (foo::bar virtual table)
3009 __vt_foo (foo virtual table, new style with thunks)
3010 _3foo$varname (static data member)
3011 _Q22rs2tu$vw (static data member)
3012 __t6vector1Zii (constructor with template)
3013 __thunk_4__$_7ostream (virtual function thunk)
3017 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
3023 if ((*mangled
)[0] == '_' && (*mangled
)[1] != '\0'
3024 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
3025 && (*mangled
)[2] == '_')
3027 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
3029 work
-> destructor
+= 1;
3031 else if ((*mangled
)[0] == '_'
3032 && (((*mangled
)[1] == '_'
3033 && (*mangled
)[2] == 'v'
3034 && (*mangled
)[3] == 't'
3035 && (*mangled
)[4] == '_')
3036 || ((*mangled
)[1] == 'v'
3037 && (*mangled
)[2] == 't' && (*mangled
)[3] != '\0'
3038 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
3040 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
3041 and create the decl. Note that we consume the entire mangled
3042 input string, which means that demangle_signature has no work
3044 if ((*mangled
)[2] == 'v')
3045 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
3047 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
3048 while (**mangled
!= '\0')
3054 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3057 success
= demangle_template (work
, mangled
, declp
, 0, 1,
3061 if (ISDIGIT((unsigned char)*mangled
[0]))
3063 n
= consume_count(mangled
);
3064 /* We may be seeing a too-large size, or else a
3065 ".<digits>" indicating a static local symbol. In
3066 any case, declare victory and move on; *don't* try
3067 to use n to allocate. */
3068 if (n
> (int) strlen (*mangled
))
3081 n
= strcspn (*mangled
, cplus_markers
);
3083 string_appendn (declp
, *mangled
, n
);
3087 p
= strpbrk (*mangled
, cplus_markers
);
3088 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
3092 string_append (declp
, SCOPE_STRING (work
));
3103 string_append (declp
, " virtual table");
3105 else if ((*mangled
)[0] == '_'
3106 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
3107 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
3109 /* static data member, "_3foo$varname" for example */
3115 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3118 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3121 n
= consume_count (mangled
);
3122 if (n
< 0 || n
> (long) strlen (*mangled
))
3128 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
3129 && (*mangled
)[9] == 'N'
3130 && (*mangled
)[8] == (*mangled
)[10]
3131 && strchr (cplus_markers
, (*mangled
)[8]))
3133 /* A member of the anonymous namespace. There's information
3134 about what identifier or filename it was keyed to, but
3135 it's just there to make the mangled name unique; we just
3137 string_append (declp
, "{anonymous}");
3140 /* Now p points to the marker before the N, so we need to
3141 update it to the first marker after what we consumed. */
3142 p
= strpbrk (*mangled
, cplus_markers
);
3146 string_appendn (declp
, *mangled
, n
);
3149 if (success
&& (p
== *mangled
))
3151 /* Consumed everything up to the cplus_marker, append the
3154 string_append (declp
, SCOPE_STRING (work
));
3155 n
= strlen (*mangled
);
3156 string_appendn (declp
, *mangled
, n
);
3164 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
3169 delta
= consume_count (mangled
);
3172 else if (**mangled
!= '_')
3176 char *method
= internal_cplus_demangle (work
, ++*mangled
);
3181 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
3182 string_append (declp
, buf
);
3183 string_append (declp
, method
);
3185 n
= strlen (*mangled
);
3194 else if (strncmp (*mangled
, "__t", 3) == 0
3195 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
3197 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
3203 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3206 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3209 success
= do_type (work
, mangled
, declp
);
3212 if (success
&& **mangled
!= '\0')
3215 string_append (declp
, p
);
3225 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
3226 string
*result
, int namelength
)
3228 char * recurse
= (char *)NULL
;
3229 char * recurse_dem
= (char *)NULL
;
3231 recurse
= XNEWVEC (char, namelength
+ 1);
3232 memcpy (recurse
, *mangled
, namelength
);
3233 recurse
[namelength
] = '\000';
3235 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3239 string_append (result
, recurse_dem
);
3244 string_appendn (result
, *mangled
, namelength
);
3247 *mangled
+= namelength
;
3254 arm_special -- special handling of ARM/lucid mangled strings
3259 arm_special (const char **mangled,
3265 Process some special ARM style mangling forms that don't fit
3266 the normal pattern. For example:
3268 __vtbl__3foo (foo virtual table)
3269 __vtbl__3foo__3bar (bar::foo virtual table)
3274 arm_special (const char **mangled
, string
*declp
)
3280 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3282 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3283 and create the decl. Note that we consume the entire mangled
3284 input string, which means that demangle_signature has no work
3286 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3287 while (*scan
!= '\0') /* first check it can be demangled */
3289 n
= consume_count (&scan
);
3292 return (0); /* no good */
3295 if (scan
[0] == '_' && scan
[1] == '_')
3300 (*mangled
) += ARM_VTABLE_STRLEN
;
3301 while (**mangled
!= '\0')
3303 n
= consume_count (mangled
);
3305 || n
> (long) strlen (*mangled
))
3307 string_prependn (declp
, *mangled
, n
);
3309 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3311 string_prepend (declp
, "::");
3315 string_append (declp
, " virtual table");
3328 demangle_qualified -- demangle 'Q' qualified name strings
3333 demangle_qualified (struct work_stuff *, const char *mangled,
3334 string *result, int isfuncname, int append);
3338 Demangle a qualified name, such as "Q25Outer5Inner" which is
3339 the mangled form of "Outer::Inner". The demangled output is
3340 prepended or appended to the result string according to the
3341 state of the append flag.
3343 If isfuncname is nonzero, then the qualified name we are building
3344 is going to be used as a member function name, so if it is a
3345 constructor or destructor function, append an appropriate
3346 constructor or destructor name. I.E. for the above example,
3347 the result for use as a constructor is "Outer::Inner::Inner"
3348 and the result for use as a destructor is "Outer::Inner::~Inner".
3352 Numeric conversion is ASCII dependent (FIXME).
3357 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3358 string
*result
, int isfuncname
, int append
)
3365 int bindex
= register_Btype (work
);
3367 /* We only make use of ISFUNCNAME if the entity is a constructor or
3369 isfuncname
= (isfuncname
3370 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3372 string_init (&temp
);
3373 string_init (&last_name
);
3375 if ((*mangled
)[0] == 'K')
3377 /* Squangling qualified name reuse */
3380 idx
= consume_count_with_underscores (mangled
);
3381 if (idx
== -1 || idx
>= work
-> numk
)
3384 string_append (&temp
, work
-> ktypevec
[idx
]);
3387 switch ((*mangled
)[1])
3390 /* GNU mangled name with more than 9 classes. The count is preceded
3391 by an underscore (to distinguish it from the <= 9 case) and followed
3392 by an underscore. */
3394 qualifiers
= consume_count_with_underscores (mangled
);
3395 if (qualifiers
== -1)
3408 /* The count is in a single digit. */
3409 num
[0] = (*mangled
)[1];
3411 qualifiers
= atoi (num
);
3413 /* If there is an underscore after the digit, skip it. This is
3414 said to be for ARM-qualified names, but the ARM makes no
3415 mention of such an underscore. Perhaps cfront uses one. */
3416 if ((*mangled
)[2] == '_')
3431 /* Pick off the names and collect them in the temp buffer in the order
3432 in which they are found, separated by '::'. */
3434 while (qualifiers
-- > 0)
3437 string_clear (&last_name
);
3439 if (*mangled
[0] == '_')
3442 if (*mangled
[0] == 't')
3444 /* Here we always append to TEMP since we will want to use
3445 the template name without the template parameters as a
3446 constructor or destructor name. The appropriate
3447 (parameter-less) value is returned by demangle_template
3448 in LAST_NAME. We do not remember the template type here,
3449 in order to match the G++ mangling algorithm. */
3450 success
= demangle_template(work
, mangled
, &temp
,
3455 else if (*mangled
[0] == 'K')
3459 idx
= consume_count_with_underscores (mangled
);
3460 if (idx
== -1 || idx
>= work
->numk
)
3463 string_append (&temp
, work
->ktypevec
[idx
]);
3466 if (!success
) break;
3473 /* Now recursively demangle the qualifier
3474 * This is necessary to deal with templates in
3475 * mangling styles like EDG */
3476 namelength
= consume_count (mangled
);
3477 if (namelength
== -1)
3482 recursively_demangle(work
, mangled
, &temp
, namelength
);
3486 string_delete (&last_name
);
3487 success
= do_type (work
, mangled
, &last_name
);
3490 string_appends (&temp
, &last_name
);
3495 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3498 string_append (&temp
, SCOPE_STRING (work
));
3501 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3503 /* If we are using the result as a function name, we need to append
3504 the appropriate '::' separated constructor or destructor name.
3505 We do this here because this is the most convenient place, where
3506 we already have a pointer to the name and the length of the name. */
3510 string_append (&temp
, SCOPE_STRING (work
));
3511 if (work
-> destructor
& 1)
3512 string_append (&temp
, "~");
3513 string_appends (&temp
, &last_name
);
3516 /* Now either prepend the temp buffer to the result, or append it,
3517 depending upon the state of the append flag. */
3520 string_appends (result
, &temp
);
3523 if (!STRING_EMPTY (result
))
3524 string_append (&temp
, SCOPE_STRING (work
));
3525 string_prepends (result
, &temp
);
3528 string_delete (&last_name
);
3529 string_delete (&temp
);
3537 get_count -- convert an ascii count to integer, consuming tokens
3542 get_count (const char **type, int *count)
3546 Assume that *type points at a count in a mangled name; set
3547 *count to its value, and set *type to the next character after
3548 the count. There are some weird rules in effect here.
3550 If *type does not point at a string of digits, return zero.
3552 If *type points at a string of digits followed by an
3553 underscore, set *count to their value as an integer, advance
3554 *type to point *after the underscore, and return 1.
3556 If *type points at a string of digits not followed by an
3557 underscore, consume only the first digit. Set *count to its
3558 value as an integer, leave *type pointing after that digit,
3561 The excuse for this odd behavior: in the ARM and HP demangling
3562 styles, a type can be followed by a repeat count of the form
3565 `x' is a single digit specifying how many additional copies
3566 of the type to append to the argument list, and
3568 `y' is one or more digits, specifying the zero-based index of
3569 the first repeated argument in the list. Yes, as you're
3570 unmangling the name you can figure this out yourself, but
3573 So, for example, in `bar__3fooFPiN51', the first argument is a
3574 pointer to an integer (`Pi'), and then the next five arguments
3575 are the same (`N5'), and the first repeat is the function's
3576 second argument (`1').
3580 get_count (const char **type
, int *count
)
3585 if (!ISDIGIT ((unsigned char)**type
))
3589 *count
= **type
- '0';
3591 if (ISDIGIT ((unsigned char)**type
))
3601 while (ISDIGIT ((unsigned char)*p
));
3612 /* RESULT will be initialised here; it will be freed on failure. The
3613 value returned is really a type_kind_t. */
3616 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3624 const char *remembered_type
;
3626 type_kind_t tk
= tk_none
;
3628 string_init (&decl
);
3629 string_init (result
);
3634 while (success
&& !done
)
3640 /* A pointer type */
3644 if (! (work
-> options
& DMGL_JAVA
))
3645 string_prepend (&decl
, "*");
3650 /* A reference type */
3653 string_prepend (&decl
, "&");
3658 /* An rvalue reference type */
3661 string_prepend (&decl
, "&&");
3663 tk
= tk_rvalue_reference
;
3670 if (!STRING_EMPTY (&decl
)
3671 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3673 string_prepend (&decl
, "(");
3674 string_append (&decl
, ")");
3676 string_append (&decl
, "[");
3677 if (**mangled
!= '_')
3678 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3680 if (**mangled
== '_')
3682 string_append (&decl
, "]");
3686 /* A back reference to a previously seen type */
3689 if (!get_count (mangled
, &n
) || n
< 0 || n
>= work
-> ntypes
)
3694 for (i
= 0; i
< work
->nproctypes
; i
++)
3695 if (work
-> proctypevec
[i
] == n
)
3701 push_processed_type (work
, n
);
3702 remembered_type
= work
->typevec
[n
];
3703 mangled
= &remembered_type
;
3710 if (!STRING_EMPTY (&decl
)
3711 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3713 string_prepend (&decl
, "(");
3714 string_append (&decl
, ")");
3716 /* After picking off the function args, we expect to either find the
3717 function return type (preceded by an '_') or the end of the
3719 if (!demangle_nested_args (work
, mangled
, &decl
)
3720 || (**mangled
!= '_' && **mangled
!= '\0'))
3725 if (success
&& (**mangled
== '_'))
3731 type_quals
= TYPE_UNQUALIFIED
;
3733 member
= **mangled
== 'M';
3736 string_append (&decl
, ")");
3738 /* We don't need to prepend `::' for a qualified name;
3739 demangle_qualified will do that for us. */
3740 if (**mangled
!= 'Q')
3741 string_prepend (&decl
, SCOPE_STRING (work
));
3743 if (ISDIGIT ((unsigned char)**mangled
))
3745 n
= consume_count (mangled
);
3747 || (int) strlen (*mangled
) < n
)
3752 string_prependn (&decl
, *mangled
, n
);
3755 else if (**mangled
== 'X' || **mangled
== 'Y')
3758 do_type (work
, mangled
, &temp
);
3759 string_prepends (&decl
, &temp
);
3760 string_delete (&temp
);
3762 else if (**mangled
== 't')
3765 string_init (&temp
);
3766 success
= demangle_template (work
, mangled
, &temp
,
3770 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3771 string_delete (&temp
);
3775 string_delete (&temp
);
3779 else if (**mangled
== 'Q')
3781 success
= demangle_qualified (work
, mangled
, &decl
,
3793 string_prepend (&decl
, "(");
3801 type_quals
|= code_for_qualifier (**mangled
);
3809 if (*(*mangled
) != 'F')
3816 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3817 || **mangled
!= '_')
3823 if (! PRINT_ANSI_QUALIFIERS
)
3827 if (type_quals
!= TYPE_UNQUALIFIED
)
3829 APPEND_BLANK (&decl
);
3830 string_append (&decl
, qualifier_string (type_quals
));
3841 if (PRINT_ANSI_QUALIFIERS
)
3843 if (!STRING_EMPTY (&decl
))
3844 string_prepend (&decl
, " ");
3846 string_prepend (&decl
, demangle_qualifier (**mangled
));
3861 if (success
) switch (**mangled
)
3863 /* A qualified name, such as "Outer::Inner". */
3867 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3871 /* A back reference to a previously seen squangled type */
3874 if (!get_count (mangled
, &n
) || n
< 0 || n
>= work
-> numb
)
3877 string_append (result
, work
->btypevec
[n
]);
3882 /* A template parm. We substitute the corresponding argument. */
3887 idx
= consume_count_with_underscores (mangled
);
3890 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3891 || consume_count_with_underscores (mangled
) == -1)
3897 if (work
->tmpl_argvec
)
3898 string_append (result
, work
->tmpl_argvec
[idx
]);
3900 string_append_template_idx (result
, idx
);
3907 success
= demangle_fund_type (work
, mangled
, result
);
3909 tk
= (type_kind_t
) success
;
3915 if (!STRING_EMPTY (&decl
))
3917 string_append (result
, " ");
3918 string_appends (result
, &decl
);
3922 string_delete (result
);
3923 string_delete (&decl
);
3926 pop_processed_type (work
);
3929 /* Assume an integral type, if we're not sure. */
3930 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3935 /* Given a pointer to a type string that represents a fundamental type
3936 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3937 string in which the demangled output is being built in RESULT, and
3938 the WORK structure, decode the types and add them to the result.
3943 "Sl" => "signed long"
3944 "CUs" => "const unsigned short"
3946 The value returned is really a type_kind_t. */
3949 demangle_fund_type (struct work_stuff
*work
,
3950 const char **mangled
, string
*result
)
3954 char buf
[INTBUF_SIZE
+ 5 /* 'int%u_t' */];
3955 unsigned int dec
= 0;
3956 type_kind_t tk
= tk_integral
;
3958 /* First pick off any type qualifiers. There can be more than one. */
3967 if (PRINT_ANSI_QUALIFIERS
)
3969 if (!STRING_EMPTY (result
))
3970 string_prepend (result
, " ");
3971 string_prepend (result
, demangle_qualifier (**mangled
));
3977 APPEND_BLANK (result
);
3978 string_append (result
, "unsigned");
3980 case 'S': /* signed char only */
3982 APPEND_BLANK (result
);
3983 string_append (result
, "signed");
3987 APPEND_BLANK (result
);
3988 string_append (result
, "__complex");
3996 /* Now pick off the fundamental type. There can be only one. */
4005 APPEND_BLANK (result
);
4006 string_append (result
, "void");
4010 APPEND_BLANK (result
);
4011 string_append (result
, "long long");
4015 APPEND_BLANK (result
);
4016 string_append (result
, "long");
4020 APPEND_BLANK (result
);
4021 string_append (result
, "int");
4025 APPEND_BLANK (result
);
4026 string_append (result
, "short");
4030 APPEND_BLANK (result
);
4031 string_append (result
, "bool");
4036 APPEND_BLANK (result
);
4037 string_append (result
, "char");
4042 APPEND_BLANK (result
);
4043 string_append (result
, "wchar_t");
4048 APPEND_BLANK (result
);
4049 string_append (result
, "long double");
4054 APPEND_BLANK (result
);
4055 string_append (result
, "double");
4060 APPEND_BLANK (result
);
4061 string_append (result
, "float");
4066 if (!ISDIGIT ((unsigned char)**mangled
))
4074 if (**mangled
== '_')
4079 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
4082 if (**mangled
!= '_')
4092 strncpy (buf
, *mangled
, 2);
4094 *mangled
+= min (strlen (*mangled
), 2);
4096 sscanf (buf
, "%x", &dec
);
4097 sprintf (buf
, "int%u_t", dec
);
4098 APPEND_BLANK (result
);
4099 string_append (result
, buf
);
4103 /* An explicit type, such as "6mytype" or "7integer" */
4115 int bindex
= register_Btype (work
);
4117 string_init (&btype
);
4118 if (demangle_class_name (work
, mangled
, &btype
)) {
4119 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
4120 APPEND_BLANK (result
);
4121 string_appends (result
, &btype
);
4125 string_delete (&btype
);
4131 string_init (&btype
);
4132 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
4133 string_appends (result
, &btype
);
4134 string_delete (&btype
);
4142 return success
? ((int) tk
) : 0;
4146 /* Handle a template's value parameter for HP aCC (extension from ARM)
4147 **mangled points to 'S' or 'U' */
4150 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
4151 const char **mangled
, string
*result
)
4155 if (**mangled
!= 'U' && **mangled
!= 'S')
4158 unsigned_const
= (**mangled
== 'U');
4165 string_append (result
, "-");
4171 /* special case for -2^31 */
4172 string_append (result
, "-2147483648");
4179 /* We have to be looking at an integer now */
4180 if (!(ISDIGIT ((unsigned char)**mangled
)))
4183 /* We only deal with integral values for template
4184 parameters -- so it's OK to look only for digits */
4185 while (ISDIGIT ((unsigned char)**mangled
))
4187 char_str
[0] = **mangled
;
4188 string_append (result
, char_str
);
4193 string_append (result
, "U");
4195 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4196 with L or LL suffixes. pai/1997-09-03 */
4198 return 1; /* success */
4201 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4202 **mangled is pointing to the 'A' */
4205 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
4208 int literal_len
= 0;
4212 if (**mangled
!= 'A')
4217 literal_len
= consume_count (mangled
);
4219 if (literal_len
<= 0
4220 || literal_len
> (long) strlen (*mangled
))
4223 /* Literal parameters are names of arrays, functions, etc. and the
4224 canonical representation uses the address operator */
4225 string_append (result
, "&");
4227 /* Now recursively demangle the literal name */
4228 recurse
= XNEWVEC (char, literal_len
+ 1);
4229 memcpy (recurse
, *mangled
, literal_len
);
4230 recurse
[literal_len
] = '\000';
4232 recurse_dem
= cplus_demangle (recurse
, work
->options
);
4236 string_append (result
, recurse_dem
);
4241 string_appendn (result
, *mangled
, literal_len
);
4243 (*mangled
) += literal_len
;
4250 snarf_numeric_literal (const char **args
, string
*arg
)
4255 string_append (arg
, char_str
);
4258 else if (**args
== '+')
4261 if (!ISDIGIT ((unsigned char)**args
))
4264 while (ISDIGIT ((unsigned char)**args
))
4266 char_str
[0] = **args
;
4267 string_append (arg
, char_str
);
4274 /* Demangle the next argument, given by MANGLED into RESULT, which
4275 *should be an uninitialized* string. It will be initialized here,
4276 and free'd should anything go wrong. */
4279 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4281 /* Remember where we started so that we can record the type, for
4282 non-squangling type remembering. */
4283 const char *start
= *mangled
;
4285 string_init (result
);
4287 if (work
->nrepeats
> 0)
4291 if (work
->previous_argument
== 0)
4294 /* We want to reissue the previous type in this argument list. */
4295 string_appends (result
, work
->previous_argument
);
4299 if (**mangled
== 'n')
4301 /* A squangling-style repeat. */
4303 work
->nrepeats
= consume_count(mangled
);
4305 if (work
->nrepeats
<= 0)
4306 /* This was not a repeat count after all. */
4309 if (work
->nrepeats
> 9)
4311 if (**mangled
!= '_')
4312 /* The repeat count should be followed by an '_' in this
4319 /* Now, the repeat is all set up. */
4320 return do_arg (work
, mangled
, result
);
4323 /* Save the result in WORK->previous_argument so that we can find it
4324 if it's repeated. Note that saving START is not good enough: we
4325 do not want to add additional types to the back-referenceable
4326 type vector when processing a repeated type. */
4327 if (work
->previous_argument
)
4328 string_delete (work
->previous_argument
);
4330 work
->previous_argument
= XNEW (string
);
4332 if (!do_type (work
, mangled
, work
->previous_argument
))
4335 string_appends (result
, work
->previous_argument
);
4337 remember_type (work
, start
, *mangled
- start
);
4342 push_processed_type (struct work_stuff
*work
, int typevec_index
)
4344 if (work
->nproctypes
>= work
->proctypevec_size
)
4346 if (!work
->proctypevec_size
)
4348 work
->proctypevec_size
= 4;
4349 work
->proctypevec
= XNEWVEC (int, work
->proctypevec_size
);
4353 if (work
->proctypevec_size
< 16)
4354 /* Double when small. */
4355 work
->proctypevec_size
*= 2;
4358 /* Grow slower when large. */
4359 if (work
->proctypevec_size
> (INT_MAX
/ 3) * 2)
4360 xmalloc_failed (INT_MAX
);
4361 work
->proctypevec_size
= (work
->proctypevec_size
* 3 / 2);
4364 = XRESIZEVEC (int, work
->proctypevec
, work
->proctypevec_size
);
4367 work
->proctypevec
[work
->nproctypes
++] = typevec_index
;
4371 pop_processed_type (struct work_stuff
*work
)
4377 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4381 if (work
->forgetting_types
)
4384 if (work
-> ntypes
>= work
-> typevec_size
)
4386 if (work
-> typevec_size
== 0)
4388 work
-> typevec_size
= 3;
4389 work
-> typevec
= XNEWVEC (char *, work
->typevec_size
);
4393 if (work
-> typevec_size
> INT_MAX
/ 2)
4394 xmalloc_failed (INT_MAX
);
4395 work
-> typevec_size
*= 2;
4397 = XRESIZEVEC (char *, work
->typevec
, work
->typevec_size
);
4400 tem
= XNEWVEC (char, len
+ 1);
4401 memcpy (tem
, start
, len
);
4403 work
-> typevec
[work
-> ntypes
++] = tem
;
4407 /* Remember a K type class qualifier. */
4409 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4413 if (work
-> numk
>= work
-> ksize
)
4415 if (work
-> ksize
== 0)
4418 work
-> ktypevec
= XNEWVEC (char *, work
->ksize
);
4422 if (work
-> ksize
> INT_MAX
/ 2)
4423 xmalloc_failed (INT_MAX
);
4426 = XRESIZEVEC (char *, work
->ktypevec
, work
->ksize
);
4429 tem
= XNEWVEC (char, len
+ 1);
4430 memcpy (tem
, start
, len
);
4432 work
-> ktypevec
[work
-> numk
++] = tem
;
4435 /* Register a B code, and get an index for it. B codes are registered
4436 as they are seen, rather than as they are completed, so map<temp<char> >
4437 registers map<temp<char> > as B0, and temp<char> as B1 */
4440 register_Btype (struct work_stuff
*work
)
4444 if (work
-> numb
>= work
-> bsize
)
4446 if (work
-> bsize
== 0)
4449 work
-> btypevec
= XNEWVEC (char *, work
->bsize
);
4453 if (work
-> bsize
> INT_MAX
/ 2)
4454 xmalloc_failed (INT_MAX
);
4457 = XRESIZEVEC (char *, work
->btypevec
, work
->bsize
);
4460 ret
= work
-> numb
++;
4461 work
-> btypevec
[ret
] = NULL
;
4465 /* Store a value into a previously registered B code type. */
4468 remember_Btype (struct work_stuff
*work
, const char *start
,
4473 tem
= XNEWVEC (char, len
+ 1);
4474 memcpy (tem
, start
, len
);
4476 work
-> btypevec
[index
] = tem
;
4479 /* Lose all the info related to B and K type codes. */
4481 forget_B_and_K_types (struct work_stuff
*work
)
4485 while (work
-> numk
> 0)
4487 i
= --(work
-> numk
);
4488 if (work
-> ktypevec
[i
] != NULL
)
4490 free (work
-> ktypevec
[i
]);
4491 work
-> ktypevec
[i
] = NULL
;
4495 while (work
-> numb
> 0)
4497 i
= --(work
-> numb
);
4498 if (work
-> btypevec
[i
] != NULL
)
4500 free (work
-> btypevec
[i
]);
4501 work
-> btypevec
[i
] = NULL
;
4505 /* Forget the remembered types, but not the type vector itself. */
4508 forget_types (struct work_stuff
*work
)
4512 while (work
-> ntypes
> 0)
4514 i
= --(work
-> ntypes
);
4515 if (work
-> typevec
[i
] != NULL
)
4517 free (work
-> typevec
[i
]);
4518 work
-> typevec
[i
] = NULL
;
4523 /* Process the argument list part of the signature, after any class spec
4524 has been consumed, as well as the first 'F' character (if any). For
4527 "__als__3fooRT0" => process "RT0"
4528 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4530 DECLP must be already initialised, usually non-empty. It won't be freed
4533 Note that g++ differs significantly from ARM and lucid style mangling
4534 with regards to references to previously seen types. For example, given
4535 the source fragment:
4539 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4542 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4543 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4545 g++ produces the names:
4550 while lcc (and presumably other ARM style compilers as well) produces:
4552 foo__FiR3fooT1T2T1T2
4553 __ct__3fooFiR3fooT1T2T1T2
4555 Note that g++ bases its type numbers starting at zero and counts all
4556 previously seen types, while lucid/ARM bases its type numbers starting
4557 at one and only considers types after it has seen the 'F' character
4558 indicating the start of the function args. For lucid/ARM style, we
4559 account for this difference by discarding any previously seen types when
4560 we see the 'F' character, and subtracting one from the type number
4566 demangle_args (struct work_stuff
*work
, const char **mangled
,
4576 if (PRINT_ARG_TYPES
)
4578 string_append (declp
, "(");
4579 if (**mangled
== '\0')
4581 string_append (declp
, "void");
4585 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4586 || work
->nrepeats
> 0)
4588 if ((**mangled
== 'N') || (**mangled
== 'T'))
4590 temptype
= *(*mangled
)++;
4592 if (temptype
== 'N')
4594 if (!get_count (mangled
, &r
))
4603 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4605 /* If we have 10 or more types we might have more than a 1 digit
4606 index so we'll have to consume the whole count here. This
4607 will lose if the next thing is a type name preceded by a
4608 count but it's impossible to demangle that case properly
4609 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4610 Pc, ...)" or "(..., type12, char *, ...)" */
4611 if ((t
= consume_count(mangled
)) <= 0)
4618 if (!get_count (mangled
, &t
))
4623 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4627 /* Validate the type index. Protect against illegal indices from
4628 malformed type strings. */
4629 if ((t
< 0) || (t
>= work
-> ntypes
))
4633 while (work
->nrepeats
> 0 || --r
>= 0)
4635 tem
= work
-> typevec
[t
];
4636 if (need_comma
&& PRINT_ARG_TYPES
)
4638 string_append (declp
, ", ");
4640 push_processed_type (work
, t
);
4641 if (!do_arg (work
, &tem
, &arg
))
4643 pop_processed_type (work
);
4646 pop_processed_type (work
);
4647 if (PRINT_ARG_TYPES
)
4649 string_appends (declp
, &arg
);
4651 string_delete (&arg
);
4657 if (need_comma
&& PRINT_ARG_TYPES
)
4658 string_append (declp
, ", ");
4659 if (!do_arg (work
, mangled
, &arg
))
4661 if (PRINT_ARG_TYPES
)
4662 string_appends (declp
, &arg
);
4663 string_delete (&arg
);
4668 if (**mangled
== 'e')
4671 if (PRINT_ARG_TYPES
)
4675 string_append (declp
, ",");
4677 string_append (declp
, "...");
4681 if (PRINT_ARG_TYPES
)
4683 string_append (declp
, ")");
4688 /* Like demangle_args, but for demangling the argument lists of function
4689 and method pointers or references, not top-level declarations. */
4692 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4695 string
* saved_previous_argument
;
4699 /* The G++ name-mangling algorithm does not remember types on nested
4700 argument lists, unless -fsquangling is used, and in that case the
4701 type vector updated by remember_type is not used. So, we turn
4702 off remembering of types here. */
4703 ++work
->forgetting_types
;
4705 /* For the repeat codes used with -fsquangling, we must keep track of
4706 the last argument. */
4707 saved_previous_argument
= work
->previous_argument
;
4708 saved_nrepeats
= work
->nrepeats
;
4709 work
->previous_argument
= 0;
4712 /* Actually demangle the arguments. */
4713 result
= demangle_args (work
, mangled
, declp
);
4715 /* Restore the previous_argument field. */
4716 if (work
->previous_argument
)
4718 string_delete (work
->previous_argument
);
4719 free ((char *) work
->previous_argument
);
4721 work
->previous_argument
= saved_previous_argument
;
4722 --work
->forgetting_types
;
4723 work
->nrepeats
= saved_nrepeats
;
4728 /* Returns 1 if a valid function name was found or 0 otherwise. */
4731 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4732 string
*declp
, const char *scan
)
4738 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4739 string_need (declp
, 1);
4740 *(declp
-> p
) = '\0';
4742 /* Consume the function name, including the "__" separating the name
4743 from the signature. We are guaranteed that SCAN points to the
4746 (*mangled
) = scan
+ 2;
4747 /* We may be looking at an instantiation of a template function:
4748 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4749 following _F marks the start of the function arguments. Handle
4750 the template arguments first. */
4752 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4754 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4755 /* This leaves MANGLED pointing to the 'F' marking func args */
4758 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4761 /* See if we have an ARM style constructor or destructor operator.
4762 If so, then just record it, clear the decl, and return.
4763 We can't build the actual constructor/destructor decl until later,
4764 when we recover the class name from the signature. */
4766 if (strcmp (declp
-> b
, "__ct") == 0)
4768 work
-> constructor
+= 1;
4769 string_clear (declp
);
4772 else if (strcmp (declp
-> b
, "__dt") == 0)
4774 work
-> destructor
+= 1;
4775 string_clear (declp
);
4780 if (declp
->p
- declp
->b
>= 3
4781 && declp
->b
[0] == 'o'
4782 && declp
->b
[1] == 'p'
4783 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4785 /* see if it's an assignment expression */
4786 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4787 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4789 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4791 int len
= declp
->p
- declp
->b
- 10;
4792 if ((int) strlen (optable
[i
].in
) == len
4793 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4795 string_clear (declp
);
4796 string_append (declp
, "operator");
4797 string_append (declp
, optable
[i
].out
);
4798 string_append (declp
, "=");
4805 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4807 int len
= declp
->p
- declp
->b
- 3;
4808 if ((int) strlen (optable
[i
].in
) == len
4809 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4811 string_clear (declp
);
4812 string_append (declp
, "operator");
4813 string_append (declp
, optable
[i
].out
);
4819 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4820 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4822 /* type conversion operator */
4824 if (do_type (work
, &tem
, &type
))
4826 string_clear (declp
);
4827 string_append (declp
, "operator ");
4828 string_appends (declp
, &type
);
4829 string_delete (&type
);
4832 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4833 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4836 /* type conversion operator. */
4838 if (do_type (work
, &tem
, &type
))
4840 string_clear (declp
);
4841 string_append (declp
, "operator ");
4842 string_appends (declp
, &type
);
4843 string_delete (&type
);
4846 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4847 && ISLOWER((unsigned char)declp
->b
[2])
4848 && ISLOWER((unsigned char)declp
->b
[3]))
4850 if (declp
->b
[4] == '\0')
4853 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4855 if (strlen (optable
[i
].in
) == 2
4856 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4858 string_clear (declp
);
4859 string_append (declp
, "operator");
4860 string_append (declp
, optable
[i
].out
);
4867 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4870 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4872 if (strlen (optable
[i
].in
) == 3
4873 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4875 string_clear (declp
);
4876 string_append (declp
, "operator");
4877 string_append (declp
, optable
[i
].out
);
4885 /* If a function name was obtained but it's not valid, we were not
4887 if (LEN_STRING (declp
) == 1 && declp
->b
[0] == '.')
4893 /* a mini string-handling package */
4896 string_need (string
*s
, int n
)
4906 s
->p
= s
->b
= XNEWVEC (char, n
);
4909 else if (s
->e
- s
->p
< n
)
4912 if (n
> INT_MAX
/ 2 - tem
)
4913 xmalloc_failed (INT_MAX
);
4916 s
->b
= XRESIZEVEC (char, s
->b
, n
);
4923 string_delete (string
*s
)
4928 s
->b
= s
->e
= s
->p
= NULL
;
4933 string_init (string
*s
)
4935 s
->b
= s
->p
= s
->e
= NULL
;
4939 string_clear (string
*s
)
4947 string_empty (string
*s
)
4949 return (s
->b
== s
->p
);
4955 string_append (string
*p
, const char *s
)
4958 if (s
== NULL
|| *s
== '\0')
4962 memcpy (p
->p
, s
, n
);
4967 string_appends (string
*p
, string
*s
)
4975 memcpy (p
->p
, s
->b
, n
);
4981 string_appendn (string
*p
, const char *s
, int n
)
4986 memcpy (p
->p
, s
, n
);
4992 string_prepend (string
*p
, const char *s
)
4994 if (s
!= NULL
&& *s
!= '\0')
4996 string_prependn (p
, s
, strlen (s
));
5001 string_prepends (string
*p
, string
*s
)
5005 string_prependn (p
, s
->b
, s
->p
- s
->b
);
5010 string_prependn (string
*p
, const char *s
, int n
)
5017 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
5021 memcpy (p
->b
, s
, n
);
5027 string_append_template_idx (string
*s
, int idx
)
5029 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
5030 sprintf(buf
, "T%d", idx
);
5031 string_append (s
, buf
);