1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.uucp)
5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
8 This file is part of the libiberty library.
9 Libiberty is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 In addition to the permissions in the GNU Library General Public
15 License, the Free Software Foundation gives you unlimited permission
16 to link the compiled version of this file into combinations with other
17 programs, and to distribute those combinations without any restriction
18 coming from the use of this file. (The Library Public License
19 restrictions do apply in other respects; for example, they cover
20 modification of the file, and distribution when not linked into a
23 Libiberty is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 Library General Public License for more details.
28 You should have received a copy of the GNU Library General Public
29 License along with libiberty; see the file COPYING.LIB. If
30 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
31 Boston, MA 02110-1301, USA. */
33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
35 This file imports xmalloc and xrealloc, which are like malloc and
36 realloc except that they generate a fatal error if there is no
39 /* This file lives in both GCC and libiberty. When making changes, please
40 try not to break either. */
46 #include "safe-ctype.h"
48 #include <sys/types.h>
63 # define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */
67 #undef CURRENT_DEMANGLING_STYLE
68 #define CURRENT_DEMANGLING_STYLE work->options
70 #include "libiberty.h"
72 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
74 /* A value at least one greater than the maximum number of characters
75 that will be output when using the `%d' format with `printf'. */
76 #define INTBUF_SIZE 32
78 extern void fancy_abort (void) ATTRIBUTE_NORETURN
;
80 /* In order to allow a single demangler executable to demangle strings
81 using various common values of CPLUS_MARKER, as well as any specific
82 one set at compile time, we maintain a string containing all the
83 commonly used ones, and check to see if the marker we are looking for
84 is in that string. CPLUS_MARKER is usually '$' on systems where the
85 assembler can deal with that. Where the assembler can't, it's usually
86 '.' (but on many systems '.' is used for other things). We put the
87 current defined CPLUS_MARKER first (which defaults to '$'), followed
88 by the next most common value, followed by an explicit '$' in case
89 the value of CPLUS_MARKER is not '$'.
91 We could avoid this if we could just get g++ to tell us what the actual
92 cplus marker character is as part of the debug information, perhaps by
93 ensuring that it is the character that terminates the gcc<n>_compiled
94 marker symbol (FIXME). */
96 #if !defined (CPLUS_MARKER)
97 #define CPLUS_MARKER '$'
100 enum demangling_styles current_demangling_style
= auto_demangling
;
102 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
104 static char char_str
[2] = { '\000', '\000' };
107 set_cplus_marker_for_demangling (int ch
)
109 cplus_markers
[0] = ch
;
112 typedef struct string
/* Beware: these aren't required to be */
113 { /* '\0' terminated. */
114 char *b
; /* pointer to start of string */
115 char *p
; /* pointer after last character */
116 char *e
; /* pointer after end of allocated space */
119 /* Stuff that is shared between sub-routines.
120 Using a shared structure allows cplus_demangle to be reentrant. */
136 int static_type
; /* A static member function */
137 int temp_start
; /* index in demangled to start of template args */
138 int type_quals
; /* The type qualifiers. */
139 int dllimported
; /* Symbol imported from a PE DLL */
140 char **tmpl_argvec
; /* Template function arguments. */
141 int ntmpl_args
; /* The number of template function arguments. */
142 int forgetting_types
; /* Nonzero if we are not remembering the types
144 string
* previous_argument
; /* The last function argument demangled. */
145 int nrepeats
; /* The number of times to repeat the previous
147 int *proctypevec
; /* Indices of currently processed remembered typevecs. */
148 int proctypevec_size
;
152 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
153 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
155 static const struct optable
157 const char *const in
;
158 const char *const out
;
161 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
162 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
163 {"new", " new", 0}, /* old (1.91, and 1.x) */
164 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
165 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
166 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
167 {"as", "=", DMGL_ANSI
}, /* ansi */
168 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
169 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
170 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
171 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
172 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
173 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
174 {"plus", "+", 0}, /* old */
175 {"pl", "+", DMGL_ANSI
}, /* ansi */
176 {"apl", "+=", DMGL_ANSI
}, /* ansi */
177 {"minus", "-", 0}, /* old */
178 {"mi", "-", DMGL_ANSI
}, /* ansi */
179 {"ami", "-=", DMGL_ANSI
}, /* ansi */
180 {"mult", "*", 0}, /* old */
181 {"ml", "*", DMGL_ANSI
}, /* ansi */
182 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
183 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
184 {"convert", "+", 0}, /* old (unary +) */
185 {"negate", "-", 0}, /* old (unary -) */
186 {"trunc_mod", "%", 0}, /* old */
187 {"md", "%", DMGL_ANSI
}, /* ansi */
188 {"amd", "%=", DMGL_ANSI
}, /* ansi */
189 {"trunc_div", "/", 0}, /* old */
190 {"dv", "/", DMGL_ANSI
}, /* ansi */
191 {"adv", "/=", DMGL_ANSI
}, /* ansi */
192 {"truth_andif", "&&", 0}, /* old */
193 {"aa", "&&", DMGL_ANSI
}, /* ansi */
194 {"truth_orif", "||", 0}, /* old */
195 {"oo", "||", DMGL_ANSI
}, /* ansi */
196 {"truth_not", "!", 0}, /* old */
197 {"nt", "!", DMGL_ANSI
}, /* ansi */
198 {"postincrement","++", 0}, /* old */
199 {"pp", "++", DMGL_ANSI
}, /* ansi */
200 {"postdecrement","--", 0}, /* old */
201 {"mm", "--", DMGL_ANSI
}, /* ansi */
202 {"bit_ior", "|", 0}, /* old */
203 {"or", "|", DMGL_ANSI
}, /* ansi */
204 {"aor", "|=", DMGL_ANSI
}, /* ansi */
205 {"bit_xor", "^", 0}, /* old */
206 {"er", "^", DMGL_ANSI
}, /* ansi */
207 {"aer", "^=", DMGL_ANSI
}, /* ansi */
208 {"bit_and", "&", 0}, /* old */
209 {"ad", "&", DMGL_ANSI
}, /* ansi */
210 {"aad", "&=", DMGL_ANSI
}, /* ansi */
211 {"bit_not", "~", 0}, /* old */
212 {"co", "~", DMGL_ANSI
}, /* ansi */
213 {"call", "()", 0}, /* old */
214 {"cl", "()", DMGL_ANSI
}, /* ansi */
215 {"alshift", "<<", 0}, /* old */
216 {"ls", "<<", DMGL_ANSI
}, /* ansi */
217 {"als", "<<=", DMGL_ANSI
}, /* ansi */
218 {"arshift", ">>", 0}, /* old */
219 {"rs", ">>", DMGL_ANSI
}, /* ansi */
220 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
221 {"component", "->", 0}, /* old */
222 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
223 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
224 {"indirect", "*", 0}, /* old */
225 {"method_call", "->()", 0}, /* old */
226 {"addr", "&", 0}, /* old (unary &) */
227 {"array", "[]", 0}, /* old */
228 {"vc", "[]", DMGL_ANSI
}, /* ansi */
229 {"compound", ", ", 0}, /* old */
230 {"cm", ", ", DMGL_ANSI
}, /* ansi */
231 {"cond", "?:", 0}, /* old */
232 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
233 {"max", ">?", 0}, /* old */
234 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
235 {"min", "<?", 0}, /* old */
236 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
237 {"nop", "", 0}, /* old (for operator=) */
238 {"rm", "->*", DMGL_ANSI
}, /* ansi */
239 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
242 /* These values are used to indicate the various type varieties.
243 They are all non-zero so that they can be used as `success'
245 typedef enum type_kind_t
257 const struct demangler_engine libiberty_demanglers
[] =
260 NO_DEMANGLING_STYLE_STRING
,
262 "Demangling disabled"
266 AUTO_DEMANGLING_STYLE_STRING
,
268 "Automatic selection based on executable"
272 GNU_DEMANGLING_STYLE_STRING
,
274 "GNU (g++) style demangling"
278 LUCID_DEMANGLING_STYLE_STRING
,
280 "Lucid (lcc) style demangling"
284 ARM_DEMANGLING_STYLE_STRING
,
286 "ARM style demangling"
290 HP_DEMANGLING_STYLE_STRING
,
292 "HP (aCC) style demangling"
296 EDG_DEMANGLING_STYLE_STRING
,
298 "EDG style demangling"
302 GNU_V3_DEMANGLING_STYLE_STRING
,
304 "GNU (g++) V3 ABI-style demangling"
308 JAVA_DEMANGLING_STYLE_STRING
,
310 "Java style demangling"
314 GNAT_DEMANGLING_STYLE_STRING
,
316 "GNAT style demangling"
320 DLANG_DEMANGLING_STYLE_STRING
,
322 "DLANG style demangling"
326 NULL
, unknown_demangling
, NULL
330 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
331 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
332 string_append(str, " ");}
333 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
335 /* The scope separator appropriate for the language being demangled. */
337 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
339 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
340 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
342 /* Prototypes for local functions */
344 static void delete_work_stuff (struct work_stuff
*);
346 static void delete_non_B_K_work_stuff (struct work_stuff
*);
348 static char *mop_up (struct work_stuff
*, string
*, int);
350 static void squangle_mop_up (struct work_stuff
*);
352 static void work_stuff_copy_to_from (struct work_stuff
*, struct work_stuff
*);
356 demangle_method_args (struct work_stuff
*, const char **, string
*);
360 internal_cplus_demangle (struct work_stuff
*, const char *);
363 demangle_template_template_parm (struct work_stuff
*work
,
364 const char **, string
*);
367 demangle_template (struct work_stuff
*work
, const char **, string
*,
371 arm_pt (struct work_stuff
*, const char *, int, const char **,
375 demangle_class_name (struct work_stuff
*, const char **, string
*);
378 demangle_qualified (struct work_stuff
*, const char **, string
*,
381 static int demangle_class (struct work_stuff
*, const char **, string
*);
383 static int demangle_fund_type (struct work_stuff
*, const char **, string
*);
385 static int demangle_signature (struct work_stuff
*, const char **, string
*);
387 static int demangle_prefix (struct work_stuff
*, const char **, string
*);
389 static int gnu_special (struct work_stuff
*, const char **, string
*);
391 static int arm_special (const char **, string
*);
393 static void string_need (string
*, int);
395 static void string_delete (string
*);
398 string_init (string
*);
400 static void string_clear (string
*);
403 static int string_empty (string
*);
406 static void string_append (string
*, const char *);
408 static void string_appends (string
*, string
*);
410 static void string_appendn (string
*, const char *, int);
412 static void string_prepend (string
*, const char *);
414 static void string_prependn (string
*, const char *, int);
416 static void string_append_template_idx (string
*, int);
418 static int get_count (const char **, int *);
420 static int consume_count (const char **);
422 static int consume_count_with_underscores (const char**);
424 static int demangle_args (struct work_stuff
*, const char **, string
*);
426 static int demangle_nested_args (struct work_stuff
*, const char**, string
*);
428 static int do_type (struct work_stuff
*, const char **, string
*);
430 static int do_arg (struct work_stuff
*, const char **, string
*);
433 demangle_function_name (struct work_stuff
*, const char **, string
*,
437 iterate_demangle_function (struct work_stuff
*,
438 const char **, string
*, const char *);
440 static void remember_type (struct work_stuff
*, const char *, int);
442 static void push_processed_type (struct work_stuff
*, int);
444 static void pop_processed_type (struct work_stuff
*);
446 static void remember_Btype (struct work_stuff
*, const char *, int, int);
448 static int register_Btype (struct work_stuff
*);
450 static void remember_Ktype (struct work_stuff
*, const char *, int);
452 static void forget_types (struct work_stuff
*);
454 static void forget_B_and_K_types (struct work_stuff
*);
456 static void string_prepends (string
*, string
*);
459 demangle_template_value_parm (struct work_stuff
*, const char**,
460 string
*, type_kind_t
);
463 do_hpacc_template_const_value (struct work_stuff
*, const char **, string
*);
466 do_hpacc_template_literal (struct work_stuff
*, const char **, string
*);
468 static int snarf_numeric_literal (const char **, string
*);
470 /* There is a TYPE_QUAL value for each type qualifier. They can be
471 combined by bitwise-or to form the complete set of qualifiers for a
474 #define TYPE_UNQUALIFIED 0x0
475 #define TYPE_QUAL_CONST 0x1
476 #define TYPE_QUAL_VOLATILE 0x2
477 #define TYPE_QUAL_RESTRICT 0x4
479 static int code_for_qualifier (int);
481 static const char* qualifier_string (int);
483 static const char* demangle_qualifier (int);
485 static int demangle_expression (struct work_stuff
*, const char **, string
*,
489 demangle_integral_value (struct work_stuff
*, const char **, string
*);
492 demangle_real_value (struct work_stuff
*, const char **, string
*);
495 demangle_arm_hp_template (struct work_stuff
*, const char **, int, string
*);
498 recursively_demangle (struct work_stuff
*, const char **, string
*, int);
500 /* Translate count to integer, consuming tokens in the process.
501 Conversion terminates on the first non-digit character.
503 Trying to consume something that isn't a count results in no
504 consumption of input and a return of -1.
506 Overflow consumes the rest of the digits, and returns -1. */
509 consume_count (const char **type
)
513 if (! ISDIGIT ((unsigned char)**type
))
516 while (ISDIGIT ((unsigned char)**type
))
520 /* Check for overflow.
521 We assume that count is represented using two's-complement;
522 no power of two is divisible by ten, so if an overflow occurs
523 when multiplying by ten, the result will not be a multiple of
525 if ((count
% 10) != 0)
527 while (ISDIGIT ((unsigned char) **type
))
532 count
+= **type
- '0';
543 /* Like consume_count, but for counts that are preceded and followed
544 by '_' if they are greater than 10. Also, -1 is returned for
545 failure, since 0 can be a valid value. */
548 consume_count_with_underscores (const char **mangled
)
552 if (**mangled
== '_')
555 if (!ISDIGIT ((unsigned char)**mangled
))
558 idx
= consume_count (mangled
);
559 if (**mangled
!= '_')
560 /* The trailing underscore was missing. */
567 if (**mangled
< '0' || **mangled
> '9')
570 idx
= **mangled
- '0';
577 /* C is the code for a type-qualifier. Return the TYPE_QUAL
578 corresponding to this qualifier. */
581 code_for_qualifier (int c
)
586 return TYPE_QUAL_CONST
;
589 return TYPE_QUAL_VOLATILE
;
592 return TYPE_QUAL_RESTRICT
;
598 /* C was an invalid qualifier. */
602 /* Return the string corresponding to the qualifiers given by
606 qualifier_string (int type_quals
)
610 case TYPE_UNQUALIFIED
:
613 case TYPE_QUAL_CONST
:
616 case TYPE_QUAL_VOLATILE
:
619 case TYPE_QUAL_RESTRICT
:
622 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
623 return "const volatile";
625 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
626 return "const __restrict";
628 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
629 return "volatile __restrict";
631 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
632 return "const volatile __restrict";
638 /* TYPE_QUALS was an invalid qualifier set. */
642 /* C is the code for a type-qualifier. Return the string
643 corresponding to this qualifier. This function should only be
644 called with a valid qualifier code. */
647 demangle_qualifier (int c
)
649 return qualifier_string (code_for_qualifier (c
));
653 cplus_demangle_opname (const char *opname
, char *result
, int options
)
657 struct work_stuff work
[1];
660 len
= strlen(opname
);
663 memset ((char *) work
, 0, sizeof (work
));
664 work
->options
= options
;
666 if (opname
[0] == '_' && opname
[1] == '_'
667 && opname
[2] == 'o' && opname
[3] == 'p')
670 /* type conversion operator. */
672 if (do_type (work
, &tem
, &type
))
674 strcat (result
, "operator ");
675 strncat (result
, type
.b
, type
.p
- type
.b
);
676 string_delete (&type
);
680 else if (opname
[0] == '_' && opname
[1] == '_'
681 && ISLOWER((unsigned char)opname
[2])
682 && ISLOWER((unsigned char)opname
[3]))
684 if (opname
[4] == '\0')
688 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
690 if (strlen (optable
[i
].in
) == 2
691 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
693 strcat (result
, "operator");
694 strcat (result
, optable
[i
].out
);
702 if (opname
[2] == 'a' && opname
[5] == '\0')
706 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
708 if (strlen (optable
[i
].in
) == 3
709 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
711 strcat (result
, "operator");
712 strcat (result
, optable
[i
].out
);
723 && strchr (cplus_markers
, opname
[2]) != NULL
)
725 /* see if it's an assignment expression */
726 if (len
>= 10 /* op$assign_ */
727 && memcmp (opname
+ 3, "assign_", 7) == 0)
730 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
733 if ((int) strlen (optable
[i
].in
) == len1
734 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
736 strcat (result
, "operator");
737 strcat (result
, optable
[i
].out
);
738 strcat (result
, "=");
747 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
750 if ((int) strlen (optable
[i
].in
) == len1
751 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
753 strcat (result
, "operator");
754 strcat (result
, optable
[i
].out
);
761 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
762 && strchr (cplus_markers
, opname
[4]) != NULL
)
764 /* type conversion operator */
766 if (do_type (work
, &tem
, &type
))
768 strcat (result
, "operator ");
769 strncat (result
, type
.b
, type
.p
- type
.b
);
770 string_delete (&type
);
774 squangle_mop_up (work
);
779 /* Takes operator name as e.g. "++" and returns mangled
780 operator name (e.g. "postincrement_expr"), or NULL if not found.
782 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
783 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
786 cplus_mangle_opname (const char *opname
, int options
)
791 len
= strlen (opname
);
792 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
794 if ((int) strlen (optable
[i
].out
) == len
795 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
796 && memcmp (optable
[i
].out
, opname
, len
) == 0)
797 return optable
[i
].in
;
802 /* Add a routine to set the demangling style to be sure it is valid and
803 allow for any demangler initialization that maybe necessary. */
805 enum demangling_styles
806 cplus_demangle_set_style (enum demangling_styles style
)
808 const struct demangler_engine
*demangler
= libiberty_demanglers
;
810 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
811 if (style
== demangler
->demangling_style
)
813 current_demangling_style
= style
;
814 return current_demangling_style
;
817 return unknown_demangling
;
820 /* Do string name to style translation */
822 enum demangling_styles
823 cplus_demangle_name_to_style (const char *name
)
825 const struct demangler_engine
*demangler
= libiberty_demanglers
;
827 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
828 if (strcmp (name
, demangler
->demangling_style_name
) == 0)
829 return demangler
->demangling_style
;
831 return unknown_demangling
;
834 /* char *cplus_demangle (const char *mangled, int options)
836 If MANGLED is a mangled function name produced by GNU C++, then
837 a pointer to a @code{malloc}ed string giving a C++ representation
838 of the name will be returned; otherwise NULL will be returned.
839 It is the caller's responsibility to free the string which
842 The OPTIONS arg may contain one or more of the following bits:
844 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
846 DMGL_PARAMS Function parameters are included.
850 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
851 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
852 cplus_demangle ("foo__1Ai", 0) => "A::foo"
854 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
855 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
856 cplus_demangle ("foo__1Afe", 0) => "A::foo"
858 Note that any leading underscores, or other such characters prepended by
859 the compilation system, are presumed to have already been stripped from
863 cplus_demangle (const char *mangled
, int options
)
866 struct work_stuff work
[1];
868 if (current_demangling_style
== no_demangling
)
869 return xstrdup (mangled
);
871 memset ((char *) work
, 0, sizeof (work
));
872 work
->options
= options
;
873 if ((work
->options
& DMGL_STYLE_MASK
) == 0)
874 work
->options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
876 /* The V3 ABI demangling is implemented elsewhere. */
877 if (GNU_V3_DEMANGLING
|| AUTO_DEMANGLING
)
879 ret
= cplus_demangle_v3 (mangled
, work
->options
);
880 if (ret
|| GNU_V3_DEMANGLING
)
886 ret
= java_demangle_v3 (mangled
);
892 return ada_demangle (mangled
, options
);
894 if (DLANG_DEMANGLING
)
896 ret
= dlang_demangle (mangled
, options
);
901 ret
= internal_cplus_demangle (work
, mangled
);
902 squangle_mop_up (work
);
906 /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
909 ada_demangle (const char *mangled
, int option ATTRIBUTE_UNUSED
)
914 char *demangled
= NULL
;
916 /* Discard leading _ada_, which is used for library level subprograms. */
917 if (strncmp (mangled
, "_ada_", 5) == 0)
920 /* All ada unit names are lower-case. */
921 if (!ISLOWER (mangled
[0]))
924 /* Most of the demangling will trivially remove chars. Operator names
925 may add one char but because they are always preceeded by '__' which is
926 replaced by '.', they eventually never expand the size.
927 A few special names such as '___elabs' add a few chars (at most 7), but
928 they occur only once. */
929 len0
= strlen (mangled
) + 7 + 1;
930 demangled
= XNEWVEC (char, len0
);
936 /* An entity names is expected. */
939 /* An identifier, which is always lower case. */
942 while (ISLOWER(*p
) || ISDIGIT (*p
)
943 || (p
[0] == '_' && (ISLOWER (p
[1]) || ISDIGIT (p
[1]))));
945 else if (p
[0] == 'O')
947 /* An operator name. */
948 static const char * const operators
[][2] =
949 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
950 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
951 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
952 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
953 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
954 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
955 {"Oexpon", "**"}, {NULL
, NULL
}};
958 for (k
= 0; operators
[k
][0] != NULL
; k
++)
960 size_t slen
= strlen (operators
[k
][0]);
961 if (strncmp (p
, operators
[k
][0], slen
) == 0)
964 slen
= strlen (operators
[k
][1]);
966 memcpy (d
, operators
[k
][1], slen
);
972 /* Operator not found. */
973 if (operators
[k
][0] == NULL
)
978 /* Not a GNAT encoding. */
982 /* The name can be directly followed by some uppercase letters. */
983 if (p
[0] == 'T' && p
[1] == 'K')
986 if (p
[2] == 'B' && p
[3] == 0)
988 /* Subprogram for task body. */
991 else if (p
[2] == '_' && p
[3] == '_')
993 /* Inner declarations in a task. */
1001 if (p
[0] == 'E' && p
[1] == 0)
1003 /* Exception name. */
1006 if ((p
[0] == 'P' || p
[0] == 'N') && p
[1] == 0)
1008 /* Protected type subprogram. */
1011 if ((*p
== 'N' || *p
== 'S') && p
[1] == 0)
1013 /* Enumerated type name table. */
1020 while (p
[0] == 'n' || p
[0] == 'b')
1023 if (p
[0] == 'S' && p
[1] != 0 && (p
[2] == '_' || p
[2] == 0))
1025 /* Stream operations. */
1048 else if (p
[0] == 'D')
1050 /* Controlled type operation. */
1073 /* Standard separator. Handled first. */
1078 /* Overloading number. */
1081 while (ISDIGIT (*p
) || (p
[0] == '_' && ISDIGIT (p
[1])));
1085 while (p
[0] == 'n' || p
[0] == 'b')
1089 else if (p
[0] == '_' && p
[1] != '_')
1091 /* Special names. */
1092 static const char * const special
[][2] = {
1093 { "_elabb", "'Elab_Body" },
1094 { "_elabs", "'Elab_Spec" },
1095 { "_size", "'Size" },
1096 { "_alignment", "'Alignment" },
1097 { "_assign", ".\":=\"" },
1102 for (k
= 0; special
[k
][0] != NULL
; k
++)
1104 size_t slen
= strlen (special
[k
][0]);
1105 if (strncmp (p
, special
[k
][0], slen
) == 0)
1108 slen
= strlen (special
[k
][1]);
1109 memcpy (d
, special
[k
][1], slen
);
1114 if (special
[k
][0] != NULL
)
1125 else if (p
[1] == 'B' || p
[1] == 'E')
1127 /* Entry Body or barrier Evaluation. */
1129 while (ISDIGIT (*p
))
1131 if (p
[0] == 's' && p
[1] == 0)
1140 if (p
[0] == '.' && ISDIGIT (p
[1]))
1142 /* Nested subprogram. */
1144 while (ISDIGIT (*p
))
1149 /* End of mangled name. */
1159 XDELETEVEC (demangled
);
1160 len0
= strlen (mangled
);
1161 demangled
= XNEWVEC (char, len0
+ 3);
1163 if (mangled
[0] == '<')
1164 strcpy (demangled
, mangled
);
1166 sprintf (demangled
, "<%s>", mangled
);
1171 /* This function performs most of what cplus_demangle use to do, but
1172 to be able to demangle a name with a B, K or n code, we need to
1173 have a longer term memory of what types have been seen. The original
1174 now initializes and cleans up the squangle code info, while internal
1175 calls go directly to this routine to avoid resetting that info. */
1178 internal_cplus_demangle (struct work_stuff
*work
, const char *mangled
)
1183 char *demangled
= NULL
;
1185 s1
= work
->constructor
;
1186 s2
= work
->destructor
;
1187 s3
= work
->static_type
;
1188 s4
= work
->type_quals
;
1189 work
->constructor
= work
->destructor
= 0;
1190 work
->type_quals
= TYPE_UNQUALIFIED
;
1191 work
->dllimported
= 0;
1193 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
1195 string_init (&decl
);
1197 /* First check to see if gnu style demangling is active and if the
1198 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1199 recognize one of the gnu special forms rather than looking for a
1200 standard prefix. In particular, don't worry about whether there
1201 is a "__" string in the mangled string. Consider "_$_5__foo" for
1204 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
1206 success
= gnu_special (work
, &mangled
, &decl
);
1209 delete_work_stuff (work
);
1210 string_delete (&decl
);
1215 success
= demangle_prefix (work
, &mangled
, &decl
);
1217 if (success
&& (*mangled
!= '\0'))
1219 success
= demangle_signature (work
, &mangled
, &decl
);
1221 if (work
->constructor
== 2)
1223 string_prepend (&decl
, "global constructors keyed to ");
1224 work
->constructor
= 0;
1226 else if (work
->destructor
== 2)
1228 string_prepend (&decl
, "global destructors keyed to ");
1229 work
->destructor
= 0;
1231 else if (work
->dllimported
== 1)
1233 string_prepend (&decl
, "import stub for ");
1234 work
->dllimported
= 0;
1236 demangled
= mop_up (work
, &decl
, success
);
1238 work
->constructor
= s1
;
1239 work
->destructor
= s2
;
1240 work
->static_type
= s3
;
1241 work
->type_quals
= s4
;
1246 /* Clear out and squangling related storage */
1248 squangle_mop_up (struct work_stuff
*work
)
1250 /* clean up the B and K type mangling types. */
1251 forget_B_and_K_types (work
);
1252 if (work
-> btypevec
!= NULL
)
1254 free ((char *) work
-> btypevec
);
1255 work
->btypevec
= NULL
;
1258 if (work
-> ktypevec
!= NULL
)
1260 free ((char *) work
-> ktypevec
);
1261 work
->ktypevec
= NULL
;
1267 /* Copy the work state and storage. */
1270 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1274 delete_work_stuff (to
);
1276 /* Shallow-copy scalars. */
1277 memcpy (to
, from
, sizeof (*to
));
1279 /* Deep-copy dynamic storage. */
1280 if (from
->typevec_size
)
1281 to
->typevec
= XNEWVEC (char *, from
->typevec_size
);
1283 for (i
= 0; i
< from
->ntypes
; i
++)
1285 int len
= strlen (from
->typevec
[i
]) + 1;
1287 to
->typevec
[i
] = XNEWVEC (char, len
);
1288 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1292 to
->ktypevec
= XNEWVEC (char *, from
->ksize
);
1294 for (i
= 0; i
< from
->numk
; i
++)
1296 int len
= strlen (from
->ktypevec
[i
]) + 1;
1298 to
->ktypevec
[i
] = XNEWVEC (char, len
);
1299 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1303 to
->btypevec
= XNEWVEC (char *, from
->bsize
);
1305 for (i
= 0; i
< from
->numb
; i
++)
1307 int len
= strlen (from
->btypevec
[i
]) + 1;
1309 to
->btypevec
[i
] = XNEWVEC (char , len
);
1310 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1313 if (from
->proctypevec
)
1315 XDUPVEC (int, from
->proctypevec
, from
->proctypevec_size
);
1317 if (from
->ntmpl_args
)
1318 to
->tmpl_argvec
= XNEWVEC (char *, from
->ntmpl_args
);
1320 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1322 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1324 to
->tmpl_argvec
[i
] = XNEWVEC (char, len
);
1325 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1328 if (from
->previous_argument
)
1330 to
->previous_argument
= XNEW (string
);
1331 string_init (to
->previous_argument
);
1332 string_appends (to
->previous_argument
, from
->previous_argument
);
1337 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1340 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1342 /* Discard the remembered types, if any. */
1344 forget_types (work
);
1345 if (work
->typevec
!= NULL
)
1347 free ((char *) work
->typevec
);
1348 work
->typevec
= NULL
;
1349 work
->typevec_size
= 0;
1351 if (work
->proctypevec
!= NULL
)
1353 free (work
->proctypevec
);
1354 work
->proctypevec
= NULL
;
1355 work
->proctypevec_size
= 0;
1357 if (work
->tmpl_argvec
)
1361 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1362 free ((char*) work
->tmpl_argvec
[i
]);
1364 free ((char*) work
->tmpl_argvec
);
1365 work
->tmpl_argvec
= NULL
;
1367 if (work
->previous_argument
)
1369 string_delete (work
->previous_argument
);
1370 free ((char*) work
->previous_argument
);
1371 work
->previous_argument
= NULL
;
1376 /* Delete all dynamic storage in work_stuff. */
1378 delete_work_stuff (struct work_stuff
*work
)
1380 delete_non_B_K_work_stuff (work
);
1381 squangle_mop_up (work
);
1385 /* Clear out any mangled storage */
1388 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1390 char *demangled
= NULL
;
1392 delete_non_B_K_work_stuff (work
);
1394 /* If demangling was successful, ensure that the demangled string is null
1395 terminated and return it. Otherwise, free the demangling decl. */
1399 string_delete (declp
);
1403 string_appendn (declp
, "", 1);
1404 demangled
= declp
->b
;
1413 demangle_signature -- demangle the signature part of a mangled name
1418 demangle_signature (struct work_stuff *work, const char **mangled,
1423 Consume and demangle the signature portion of the mangled name.
1425 DECLP is the string where demangled output is being built. At
1426 entry it contains the demangled root name from the mangled name
1427 prefix. I.E. either a demangled operator name or the root function
1428 name. In some special cases, it may contain nothing.
1430 *MANGLED points to the current unconsumed location in the mangled
1431 name. As tokens are consumed and demangling is performed, the
1432 pointer is updated to continuously point at the next token to
1435 Demangling GNU style mangled names is nasty because there is no
1436 explicit token that marks the start of the outermost function
1440 demangle_signature (struct work_stuff
*work
,
1441 const char **mangled
, string
*declp
)
1445 int expect_func
= 0;
1446 int expect_return_type
= 0;
1447 const char *oldmangled
= NULL
;
1451 while (success
&& (**mangled
!= '\0'))
1456 oldmangled
= *mangled
;
1457 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1459 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1460 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1466 oldmangled
= *mangled
;
1467 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1468 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1476 /* Static member function */
1477 if (oldmangled
== NULL
)
1479 oldmangled
= *mangled
;
1482 work
-> static_type
= 1;
1488 work
->type_quals
|= code_for_qualifier (**mangled
);
1490 /* a qualified member function */
1491 if (oldmangled
== NULL
)
1492 oldmangled
= *mangled
;
1497 /* Local class name follows after "Lnnn_" */
1500 while (**mangled
&& (**mangled
!= '_'))
1511 case '0': case '1': case '2': case '3': case '4':
1512 case '5': case '6': case '7': case '8': case '9':
1513 if (oldmangled
== NULL
)
1515 oldmangled
= *mangled
;
1517 work
->temp_start
= -1; /* uppermost call to demangle_class */
1518 success
= demangle_class (work
, mangled
, declp
);
1521 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1523 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1525 /* EDG and others will have the "F", so we let the loop cycle
1526 if we are looking at one. */
1527 if (**mangled
!= 'F')
1536 success
= do_type (work
, mangled
, &s
);
1539 string_append (&s
, SCOPE_STRING (work
));
1540 string_prepends (declp
, &s
);
1550 /* ARM/HP style demangling includes a specific 'F' character after
1551 the class name. For GNU style, it is just implied. So we can
1552 safely just consume any 'F' at this point and be compatible
1553 with either style. */
1559 /* For lucid/ARM/HP style we have to forget any types we might
1560 have remembered up to this point, since they were not argument
1561 types. GNU style considers all types seen as available for
1562 back references. See comment in demangle_args() */
1564 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1566 forget_types (work
);
1568 success
= demangle_args (work
, mangled
, declp
);
1569 /* After picking off the function args, we expect to either
1570 find the function return type (preceded by an '_') or the
1571 end of the string. */
1572 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1575 /* At this level, we do not care about the return type. */
1576 success
= do_type (work
, mangled
, &tname
);
1577 string_delete (&tname
);
1584 string_init(&trawname
);
1585 string_init(&tname
);
1586 if (oldmangled
== NULL
)
1588 oldmangled
= *mangled
;
1590 success
= demangle_template (work
, mangled
, &tname
,
1594 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1596 string_append (&tname
, SCOPE_STRING (work
));
1598 string_prepends(declp
, &tname
);
1599 if (work
-> destructor
& 1)
1601 string_prepend (&trawname
, "~");
1602 string_appends (declp
, &trawname
);
1603 work
->destructor
-= 1;
1605 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1607 string_appends (declp
, &trawname
);
1608 work
->constructor
-= 1;
1610 string_delete(&trawname
);
1611 string_delete(&tname
);
1617 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1619 /* Read the return type. */
1623 success
= do_type (work
, mangled
, &return_type
);
1624 APPEND_BLANK (&return_type
);
1626 string_prepends (declp
, &return_type
);
1627 string_delete (&return_type
);
1631 /* At the outermost level, we cannot have a return type specified,
1632 so if we run into another '_' at this point we are dealing with
1633 a mangled name that is either bogus, or has been mangled by
1634 some algorithm we don't know how to deal with. So just
1635 reject the entire demangling. */
1636 /* However, "_nnn" is an expected suffix for alternate entry point
1637 numbered nnn for a function, with HP aCC, so skip over that
1638 without reporting failure. pai/1997-09-04 */
1642 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1650 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1652 /* A G++ template function. Read the template arguments. */
1653 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1655 if (!(work
->constructor
& 1))
1656 expect_return_type
= 1;
1665 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1667 /* Assume we have stumbled onto the first outermost function
1668 argument token, and start processing args. */
1670 success
= demangle_args (work
, mangled
, declp
);
1674 /* Non-GNU demanglers use a specific token to mark the start
1675 of the outermost function argument tokens. Typically 'F',
1676 for ARM/HP-demangling, for example. So if we find something
1677 we are not prepared for, it must be an error. */
1683 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1686 if (success
&& expect_func
)
1689 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1691 forget_types (work
);
1693 success
= demangle_args (work
, mangled
, declp
);
1694 /* Since template include the mangling of their return types,
1695 we must set expect_func to 0 so that we don't try do
1696 demangle more arguments the next time we get here. */
1701 if (success
&& !func_done
)
1703 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1705 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1706 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1707 first case, and need to ensure that the '(void)' gets added to
1708 the current declp. Note that with ARM/HP, the first case
1709 represents the name of a static data member 'foo::bar',
1710 which is in the current declp, so we leave it alone. */
1711 success
= demangle_args (work
, mangled
, declp
);
1714 if (success
&& PRINT_ARG_TYPES
)
1716 if (work
->static_type
)
1717 string_append (declp
, " static");
1718 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1720 APPEND_BLANK (declp
);
1721 string_append (declp
, qualifier_string (work
->type_quals
));
1731 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1736 if (work
-> static_type
)
1738 string_append (declp
, *mangled
+ 1);
1739 *mangled
+= strlen (*mangled
);
1744 success
= demangle_args (work
, mangled
, declp
);
1752 demangle_template_template_parm (struct work_stuff
*work
,
1753 const char **mangled
, string
*tname
)
1761 string_append (tname
, "template <");
1762 /* get size of template parameter list */
1763 if (get_count (mangled
, &r
))
1765 for (i
= 0; i
< r
; i
++)
1769 string_append (tname
, ", ");
1772 /* Z for type parameters */
1773 if (**mangled
== 'Z')
1776 string_append (tname
, "class");
1778 /* z for template parameters */
1779 else if (**mangled
== 'z')
1783 demangle_template_template_parm (work
, mangled
, tname
);
1791 /* temp is initialized in do_type */
1792 success
= do_type (work
, mangled
, &temp
);
1795 string_appends (tname
, &temp
);
1797 string_delete(&temp
);
1807 if (tname
->p
[-1] == '>')
1808 string_append (tname
, " ");
1809 string_append (tname
, "> class");
1814 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1815 string
*s
, type_kind_t tk
)
1817 int need_operator
= 0;
1821 string_appendn (s
, "(", 1);
1823 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1832 len
= strlen (*mangled
);
1834 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1836 size_t l
= strlen (optable
[i
].in
);
1839 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1841 string_appendn (s
, " ", 1);
1842 string_append (s
, optable
[i
].out
);
1843 string_appendn (s
, " ", 1);
1856 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1859 if (**mangled
!= 'W')
1863 string_appendn (s
, ")", 1);
1871 demangle_integral_value (struct work_stuff
*work
,
1872 const char **mangled
, string
*s
)
1876 if (**mangled
== 'E')
1877 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1878 else if (**mangled
== 'Q' || **mangled
== 'K')
1879 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1884 /* By default, we let the number decide whether we shall consume an
1886 int multidigit_without_leading_underscore
= 0;
1887 int leave_following_underscore
= 0;
1891 if (**mangled
== '_')
1893 if (mangled
[0][1] == 'm')
1895 /* Since consume_count_with_underscores does not handle the
1896 `m'-prefix we must do it here, using consume_count and
1897 adjusting underscores: we have to consume the underscore
1898 matching the prepended one. */
1899 multidigit_without_leading_underscore
= 1;
1900 string_appendn (s
, "-", 1);
1905 /* Do not consume a following underscore;
1906 consume_count_with_underscores will consume what
1907 should be consumed. */
1908 leave_following_underscore
= 1;
1913 /* Negative numbers are indicated with a leading `m'. */
1914 if (**mangled
== 'm')
1916 string_appendn (s
, "-", 1);
1919 /* Since consume_count_with_underscores does not handle
1920 multi-digit numbers that do not start with an underscore,
1921 and this number can be an integer template parameter,
1922 we have to call consume_count. */
1923 multidigit_without_leading_underscore
= 1;
1924 /* These multi-digit numbers never end on an underscore,
1925 so if there is one then don't eat it. */
1926 leave_following_underscore
= 1;
1929 /* We must call consume_count if we expect to remove a trailing
1930 underscore, since consume_count_with_underscores expects
1931 the leading underscore (that we consumed) if it is to handle
1932 multi-digit numbers. */
1933 if (multidigit_without_leading_underscore
)
1934 value
= consume_count (mangled
);
1936 value
= consume_count_with_underscores (mangled
);
1940 char buf
[INTBUF_SIZE
];
1941 sprintf (buf
, "%d", value
);
1942 string_append (s
, buf
);
1944 /* Numbers not otherwise delimited, might have an underscore
1945 appended as a delimeter, which we should skip.
1947 ??? This used to always remove a following underscore, which
1948 is wrong. If other (arbitrary) cases are followed by an
1949 underscore, we need to do something more radical. */
1951 if ((value
> 9 || multidigit_without_leading_underscore
)
1952 && ! leave_following_underscore
1953 && **mangled
== '_')
1964 /* Demangle the real value in MANGLED. */
1967 demangle_real_value (struct work_stuff
*work
,
1968 const char **mangled
, string
*s
)
1970 if (**mangled
== 'E')
1971 return demangle_expression (work
, mangled
, s
, tk_real
);
1973 if (**mangled
== 'm')
1975 string_appendn (s
, "-", 1);
1978 while (ISDIGIT ((unsigned char)**mangled
))
1980 string_appendn (s
, *mangled
, 1);
1983 if (**mangled
== '.') /* fraction */
1985 string_appendn (s
, ".", 1);
1987 while (ISDIGIT ((unsigned char)**mangled
))
1989 string_appendn (s
, *mangled
, 1);
1993 if (**mangled
== 'e') /* exponent */
1995 string_appendn (s
, "e", 1);
1997 while (ISDIGIT ((unsigned char)**mangled
))
1999 string_appendn (s
, *mangled
, 1);
2008 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
2009 string
*s
, type_kind_t tk
)
2013 if (**mangled
== 'Y')
2015 /* The next argument is a template parameter. */
2019 idx
= consume_count_with_underscores (mangled
);
2021 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2022 || consume_count_with_underscores (mangled
) == -1)
2024 if (work
->tmpl_argvec
)
2025 string_append (s
, work
->tmpl_argvec
[idx
]);
2027 string_append_template_idx (s
, idx
);
2029 else if (tk
== tk_integral
)
2030 success
= demangle_integral_value (work
, mangled
, s
);
2031 else if (tk
== tk_char
)
2035 if (**mangled
== 'm')
2037 string_appendn (s
, "-", 1);
2040 string_appendn (s
, "'", 1);
2041 val
= consume_count(mangled
);
2048 string_appendn (s
, &tmp
[0], 1);
2049 string_appendn (s
, "'", 1);
2052 else if (tk
== tk_bool
)
2054 int val
= consume_count (mangled
);
2056 string_appendn (s
, "false", 5);
2058 string_appendn (s
, "true", 4);
2062 else if (tk
== tk_real
)
2063 success
= demangle_real_value (work
, mangled
, s
);
2064 else if (tk
== tk_pointer
|| tk
== tk_reference
2065 || tk
== tk_rvalue_reference
)
2067 if (**mangled
== 'Q')
2068 success
= demangle_qualified (work
, mangled
, s
,
2073 int symbol_len
= consume_count (mangled
);
2074 if (symbol_len
== -1
2075 || symbol_len
> (long) strlen (*mangled
))
2077 if (symbol_len
== 0)
2078 string_appendn (s
, "0", 1);
2081 char *p
= XNEWVEC (char, symbol_len
+ 1), *q
;
2082 strncpy (p
, *mangled
, symbol_len
);
2083 p
[symbol_len
] = '\0';
2084 /* We use cplus_demangle here, rather than
2085 internal_cplus_demangle, because the name of the entity
2086 mangled here does not make use of any of the squangling
2087 or type-code information we have built up thus far; it is
2088 mangled independently. */
2089 q
= cplus_demangle (p
, work
->options
);
2090 if (tk
== tk_pointer
)
2091 string_appendn (s
, "&", 1);
2092 /* FIXME: Pointer-to-member constants should get a
2093 qualifying class name here. */
2096 string_append (s
, q
);
2100 string_append (s
, p
);
2103 *mangled
+= symbol_len
;
2110 /* Demangle the template name in MANGLED. The full name of the
2111 template (e.g., S<int>) is placed in TNAME. The name without the
2112 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2113 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2114 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2115 the template is remembered in the list of back-referenceable
2119 demangle_template (struct work_stuff
*work
, const char **mangled
,
2120 string
*tname
, string
*trawname
,
2121 int is_type
, int remember
)
2127 int is_java_array
= 0;
2133 /* get template name */
2134 if (**mangled
== 'z')
2140 idx
= consume_count_with_underscores (mangled
);
2142 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2143 || consume_count_with_underscores (mangled
) == -1)
2146 if (work
->tmpl_argvec
)
2148 string_append (tname
, work
->tmpl_argvec
[idx
]);
2150 string_append (trawname
, work
->tmpl_argvec
[idx
]);
2154 string_append_template_idx (tname
, idx
);
2156 string_append_template_idx (trawname
, idx
);
2161 if ((r
= consume_count (mangled
)) <= 0
2162 || (int) strlen (*mangled
) < r
)
2166 is_java_array
= (work
-> options
& DMGL_JAVA
)
2167 && strncmp (*mangled
, "JArray1Z", 8) == 0;
2168 if (! is_java_array
)
2170 string_appendn (tname
, *mangled
, r
);
2173 string_appendn (trawname
, *mangled
, r
);
2178 string_append (tname
, "<");
2179 /* get size of template parameter list */
2180 if (!get_count (mangled
, &r
))
2186 /* Create an array for saving the template argument values. */
2187 work
->tmpl_argvec
= XNEWVEC (char *, r
);
2188 work
->ntmpl_args
= r
;
2189 for (i
= 0; i
< r
; i
++)
2190 work
->tmpl_argvec
[i
] = 0;
2192 for (i
= 0; i
< r
; i
++)
2196 string_append (tname
, ", ");
2198 /* Z for type parameters */
2199 if (**mangled
== 'Z')
2202 /* temp is initialized in do_type */
2203 success
= do_type (work
, mangled
, &temp
);
2206 string_appends (tname
, &temp
);
2210 /* Save the template argument. */
2211 int len
= temp
.p
- temp
.b
;
2212 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2213 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2214 work
->tmpl_argvec
[i
][len
] = '\0';
2217 string_delete(&temp
);
2223 /* z for template parameters */
2224 else if (**mangled
== 'z')
2228 success
= demangle_template_template_parm (work
, mangled
, tname
);
2231 && (r2
= consume_count (mangled
)) > 0
2232 && (int) strlen (*mangled
) >= r2
)
2234 string_append (tname
, " ");
2235 string_appendn (tname
, *mangled
, r2
);
2238 /* Save the template argument. */
2240 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2241 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2242 work
->tmpl_argvec
[i
][len
] = '\0';
2256 /* otherwise, value parameter */
2258 /* temp is initialized in do_type */
2259 success
= do_type (work
, mangled
, &temp
);
2260 string_delete(&temp
);
2272 success
= demangle_template_value_parm (work
, mangled
, s
,
2273 (type_kind_t
) success
);
2285 int len
= s
->p
- s
->b
;
2286 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2287 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2288 work
->tmpl_argvec
[i
][len
] = '\0';
2290 string_appends (tname
, s
);
2298 string_append (tname
, "[]");
2302 if (tname
->p
[-1] == '>')
2303 string_append (tname
, " ");
2304 string_append (tname
, ">");
2307 if (is_type
&& remember
)
2309 const int bindex
= register_Btype (work
);
2310 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2314 if (work -> static_type)
2316 string_append (declp, *mangled + 1);
2317 *mangled += strlen (*mangled);
2322 success = demangle_args (work, mangled, declp);
2330 arm_pt (struct work_stuff
*work
, const char *mangled
,
2331 int n
, const char **anchor
, const char **args
)
2333 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2334 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2335 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2338 *args
= *anchor
+ 6;
2339 len
= consume_count (args
);
2342 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2348 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2350 if ((*anchor
= strstr (mangled
, "__tm__"))
2351 || (*anchor
= strstr (mangled
, "__ps__"))
2352 || (*anchor
= strstr (mangled
, "__pt__")))
2355 *args
= *anchor
+ 6;
2356 len
= consume_count (args
);
2359 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2365 else if ((*anchor
= strstr (mangled
, "__S")))
2368 *args
= *anchor
+ 3;
2369 len
= consume_count (args
);
2372 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2384 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2385 int n
, string
*declp
)
2389 const char *e
= *mangled
+ n
;
2392 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2394 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2396 char *start_spec_args
= NULL
;
2399 /* First check for and omit template specialization pseudo-arguments,
2400 such as in "Spec<#1,#1.*>" */
2401 start_spec_args
= strchr (*mangled
, '<');
2402 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2403 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2405 string_appendn (declp
, *mangled
, n
);
2406 (*mangled
) += n
+ 1;
2408 if (work
->temp_start
== -1) /* non-recursive call */
2409 work
->temp_start
= declp
->p
- declp
->b
;
2411 /* We want to unconditionally demangle parameter types in
2412 template parameters. */
2413 hold_options
= work
->options
;
2414 work
->options
|= DMGL_PARAMS
;
2416 string_append (declp
, "<");
2419 string_delete (&arg
);
2423 /* 'T' signals a type parameter */
2425 if (!do_type (work
, mangled
, &arg
))
2426 goto hpacc_template_args_done
;
2431 /* 'U' or 'S' signals an integral value */
2432 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2433 goto hpacc_template_args_done
;
2437 /* 'A' signals a named constant expression (literal) */
2438 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2439 goto hpacc_template_args_done
;
2443 /* Today, 1997-09-03, we have only the above types
2444 of template parameters */
2445 /* FIXME: maybe this should fail and return null */
2446 goto hpacc_template_args_done
;
2448 string_appends (declp
, &arg
);
2449 /* Check if we're at the end of template args.
2450 0 if at end of static member of template class,
2451 _ if done with template args for a function */
2452 if ((**mangled
== '\000') || (**mangled
== '_'))
2455 string_append (declp
, ",");
2457 hpacc_template_args_done
:
2458 string_append (declp
, ">");
2459 string_delete (&arg
);
2460 if (**mangled
== '_')
2462 work
->options
= hold_options
;
2465 /* ARM template? (Also handles HP cfront extensions) */
2466 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2472 string_appendn (declp
, *mangled
, p
- *mangled
);
2473 if (work
->temp_start
== -1) /* non-recursive call */
2474 work
->temp_start
= declp
->p
- declp
->b
;
2476 /* We want to unconditionally demangle parameter types in
2477 template parameters. */
2478 hold_options
= work
->options
;
2479 work
->options
|= DMGL_PARAMS
;
2481 string_append (declp
, "<");
2482 /* should do error checking here */
2484 string_delete (&arg
);
2486 /* Check for type or literal here */
2489 /* HP cfront extensions to ARM for template args */
2490 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2491 /* FIXME: We handle only numeric literals for HP cfront */
2493 /* A typed constant value follows */
2495 if (!do_type (work
, &args
, &type_str
))
2496 goto cfront_template_args_done
;
2497 string_append (&arg
, "(");
2498 string_appends (&arg
, &type_str
);
2499 string_delete (&type_str
);
2500 string_append (&arg
, ")");
2502 goto cfront_template_args_done
;
2504 /* Now snarf a literal value following 'L' */
2505 if (!snarf_numeric_literal (&args
, &arg
))
2506 goto cfront_template_args_done
;
2510 /* Snarf a literal following 'L' */
2512 if (!snarf_numeric_literal (&args
, &arg
))
2513 goto cfront_template_args_done
;
2516 /* Not handling other HP cfront stuff */
2518 const char* old_args
= args
;
2519 if (!do_type (work
, &args
, &arg
))
2520 goto cfront_template_args_done
;
2522 /* Fail if we didn't make any progress: prevent infinite loop. */
2523 if (args
== old_args
)
2525 work
->options
= hold_options
;
2530 string_appends (declp
, &arg
);
2531 string_append (declp
, ",");
2533 cfront_template_args_done
:
2534 string_delete (&arg
);
2536 --declp
->p
; /* remove extra comma */
2537 string_append (declp
, ">");
2538 work
->options
= hold_options
;
2540 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2541 && (*mangled
)[9] == 'N'
2542 && (*mangled
)[8] == (*mangled
)[10]
2543 && strchr (cplus_markers
, (*mangled
)[8]))
2545 /* A member of the anonymous namespace. */
2546 string_append (declp
, "{anonymous}");
2550 if (work
->temp_start
== -1) /* non-recursive call only */
2551 work
->temp_start
= 0; /* disable in recursive calls */
2552 string_appendn (declp
, *mangled
, n
);
2557 /* Extract a class name, possibly a template with arguments, from the
2558 mangled string; qualifiers, local class indicators, etc. have
2559 already been dealt with */
2562 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2568 n
= consume_count (mangled
);
2571 if ((int) strlen (*mangled
) >= n
)
2573 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2584 demangle_class -- demangle a mangled class sequence
2589 demangle_class (struct work_stuff *work, const char **mangled,
2594 DECLP points to the buffer into which demangling is being done.
2596 *MANGLED points to the current token to be demangled. On input,
2597 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2598 On exit, it points to the next token after the mangled class on
2599 success, or the first unconsumed token on failure.
2601 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2602 we are demangling a constructor or destructor. In this case
2603 we prepend "class::class" or "class::~class" to DECLP.
2605 Otherwise, we prepend "class::" to the current DECLP.
2607 Reset the constructor/destructor flags once they have been
2608 "consumed". This allows demangle_class to be called later during
2609 the same demangling, to do normal class demangling.
2611 Returns 1 if demangling is successful, 0 otherwise.
2616 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2621 char *save_class_name_end
= 0;
2623 string_init (&class_name
);
2624 btype
= register_Btype (work
);
2625 if (demangle_class_name (work
, mangled
, &class_name
))
2627 save_class_name_end
= class_name
.p
;
2628 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2630 /* adjust so we don't include template args */
2631 if (work
->temp_start
&& (work
->temp_start
!= -1))
2633 class_name
.p
= class_name
.b
+ work
->temp_start
;
2635 string_prepends (declp
, &class_name
);
2636 if (work
-> destructor
& 1)
2638 string_prepend (declp
, "~");
2639 work
-> destructor
-= 1;
2643 work
-> constructor
-= 1;
2646 class_name
.p
= save_class_name_end
;
2647 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2648 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2649 string_prepend (declp
, SCOPE_STRING (work
));
2650 string_prepends (declp
, &class_name
);
2653 string_delete (&class_name
);
2658 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2659 the rightmost guess.
2661 Find the correct "__"-sequence where the function name ends and the
2662 signature starts, which is ambiguous with GNU mangling.
2663 Call demangle_signature here, so we can make sure we found the right
2664 one; *mangled will be consumed so caller will not make further calls to
2665 demangle_signature. */
2668 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2669 string
*declp
, const char *scan
)
2671 const char *mangle_init
= *mangled
;
2674 struct work_stuff work_init
;
2676 if (*(scan
+ 2) == '\0')
2679 /* Do not iterate for some demangling modes, or if there's only one
2680 "__"-sequence. This is the normal case. */
2681 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2682 || strstr (scan
+ 2, "__") == NULL
)
2683 return demangle_function_name (work
, mangled
, declp
, scan
);
2685 /* Save state so we can restart if the guess at the correct "__" was
2687 string_init (&decl_init
);
2688 string_appends (&decl_init
, declp
);
2689 memset (&work_init
, 0, sizeof work_init
);
2690 work_stuff_copy_to_from (&work_init
, work
);
2692 /* Iterate over occurrences of __, allowing names and types to have a
2693 "__" sequence in them. We must start with the first (not the last)
2694 occurrence, since "__" most often occur between independent mangled
2695 parts, hence starting at the last occurence inside a signature
2696 might get us a "successful" demangling of the signature. */
2700 if (demangle_function_name (work
, mangled
, declp
, scan
))
2702 success
= demangle_signature (work
, mangled
, declp
);
2707 /* Reset demangle state for the next round. */
2708 *mangled
= mangle_init
;
2709 string_clear (declp
);
2710 string_appends (declp
, &decl_init
);
2711 work_stuff_copy_to_from (work
, &work_init
);
2713 /* Leave this underscore-sequence. */
2716 /* Scan for the next "__" sequence. */
2717 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2720 /* Move to last "__" in this sequence. */
2721 while (*scan
&& *scan
== '_')
2726 /* Delete saved state. */
2727 delete_work_stuff (&work_init
);
2728 string_delete (&decl_init
);
2737 demangle_prefix -- consume the mangled name prefix and find signature
2742 demangle_prefix (struct work_stuff *work, const char **mangled,
2747 Consume and demangle the prefix of the mangled name.
2748 While processing the function name root, arrange to call
2749 demangle_signature if the root is ambiguous.
2751 DECLP points to the string buffer into which demangled output is
2752 placed. On entry, the buffer is empty. On exit it contains
2753 the root function name, the demangled operator name, or in some
2754 special cases either nothing or the completely demangled result.
2756 MANGLED points to the current pointer into the mangled name. As each
2757 token of the mangled name is consumed, it is updated. Upon entry
2758 the current mangled name pointer points to the first character of
2759 the mangled name. Upon exit, it should point to the first character
2760 of the signature if demangling was successful, or to the first
2761 unconsumed character if demangling of the prefix was unsuccessful.
2763 Returns 1 on success, 0 otherwise.
2767 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2774 if (strlen(*mangled
) > 6
2775 && (strncmp(*mangled
, "_imp__", 6) == 0
2776 || strncmp(*mangled
, "__imp_", 6) == 0))
2778 /* it's a symbol imported from a PE dynamic library. Check for both
2779 new style prefix _imp__ and legacy __imp_ used by older versions
2782 work
->dllimported
= 1;
2784 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2786 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2787 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2789 if ((*mangled
)[9] == 'D')
2791 /* it's a GNU global destructor to be executed at program exit */
2793 work
->destructor
= 2;
2794 if (gnu_special (work
, mangled
, declp
))
2797 else if ((*mangled
)[9] == 'I')
2799 /* it's a GNU global constructor to be executed at program init */
2801 work
->constructor
= 2;
2802 if (gnu_special (work
, mangled
, declp
))
2807 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2809 /* it's a ARM global destructor to be executed at program exit */
2811 work
->destructor
= 2;
2813 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2815 /* it's a ARM global constructor to be executed at program initial */
2817 work
->constructor
= 2;
2820 /* This block of code is a reduction in strength time optimization
2822 scan = strstr (*mangled, "__"); */
2828 scan
= strchr (scan
, '_');
2829 } while (scan
!= NULL
&& *++scan
!= '_');
2831 if (scan
!= NULL
) --scan
;
2836 /* We found a sequence of two or more '_', ensure that we start at
2837 the last pair in the sequence. */
2838 i
= strspn (scan
, "_");
2849 else if (work
-> static_type
)
2851 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2856 else if ((scan
== *mangled
)
2857 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2858 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2860 /* The ARM says nothing about the mangling of local variables.
2861 But cfront mangles local variables by prepending __<nesting_level>
2862 to them. As an extension to ARM demangling we handle this case. */
2863 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2864 && ISDIGIT ((unsigned char)scan
[2]))
2866 *mangled
= scan
+ 2;
2867 consume_count (mangled
);
2868 string_append (declp
, *mangled
);
2869 *mangled
+= strlen (*mangled
);
2874 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2875 names like __Q2_3foo3bar for nested type names. So don't accept
2876 this style of constructor for cfront demangling. A GNU
2877 style member-template constructor starts with 'H'. */
2878 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2879 work
-> constructor
+= 1;
2880 *mangled
= scan
+ 2;
2883 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2885 /* Cfront-style parameterized type. Handled later as a signature. */
2889 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2891 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2892 || (scan
[2] == 'p' && scan
[3] == 's')
2893 || (scan
[2] == 'p' && scan
[3] == 't')))
2895 /* EDG-style parameterized type. Handled later as a signature. */
2899 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2901 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2902 && (scan
[2] != 't'))
2904 /* Mangled name starts with "__". Skip over any leading '_' characters,
2905 then find the next "__" that separates the prefix from the signature.
2907 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2908 || (arm_special (mangled
, declp
) == 0))
2910 while (*scan
== '_')
2914 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2916 /* No separator (I.E. "__not_mangled"), or empty signature
2917 (I.E. "__not_mangled_either__") */
2921 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2924 else if (*(scan
+ 2) != '\0')
2926 /* Mangled name does not start with "__" but does have one somewhere
2927 in there with non empty stuff after it. Looks like a global
2928 function name. Iterate over all "__":s until the right
2930 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2934 /* Doesn't look like a mangled name */
2938 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2940 string_append (declp
, *mangled
);
2941 *mangled
+= strlen (*mangled
);
2951 gnu_special -- special handling of gnu mangled strings
2956 gnu_special (struct work_stuff *work, const char **mangled,
2962 Process some special GNU style mangling forms that don't fit
2963 the normal pattern. For example:
2965 _$_3foo (destructor for class foo)
2966 _vt$foo (foo virtual table)
2967 _vt$foo$bar (foo::bar virtual table)
2968 __vt_foo (foo virtual table, new style with thunks)
2969 _3foo$varname (static data member)
2970 _Q22rs2tu$vw (static data member)
2971 __t6vector1Zii (constructor with template)
2972 __thunk_4__$_7ostream (virtual function thunk)
2976 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2982 if ((*mangled
)[0] == '_'
2983 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2984 && (*mangled
)[2] == '_')
2986 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2988 work
-> destructor
+= 1;
2990 else if ((*mangled
)[0] == '_'
2991 && (((*mangled
)[1] == '_'
2992 && (*mangled
)[2] == 'v'
2993 && (*mangled
)[3] == 't'
2994 && (*mangled
)[4] == '_')
2995 || ((*mangled
)[1] == 'v'
2996 && (*mangled
)[2] == 't'
2997 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2999 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
3000 and create the decl. Note that we consume the entire mangled
3001 input string, which means that demangle_signature has no work
3003 if ((*mangled
)[2] == 'v')
3004 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
3006 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
3007 while (**mangled
!= '\0')
3013 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3016 success
= demangle_template (work
, mangled
, declp
, 0, 1,
3020 if (ISDIGIT((unsigned char)*mangled
[0]))
3022 n
= consume_count(mangled
);
3023 /* We may be seeing a too-large size, or else a
3024 ".<digits>" indicating a static local symbol. In
3025 any case, declare victory and move on; *don't* try
3026 to use n to allocate. */
3027 if (n
> (int) strlen (*mangled
))
3040 n
= strcspn (*mangled
, cplus_markers
);
3042 string_appendn (declp
, *mangled
, n
);
3046 p
= strpbrk (*mangled
, cplus_markers
);
3047 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
3051 string_append (declp
, SCOPE_STRING (work
));
3062 string_append (declp
, " virtual table");
3064 else if ((*mangled
)[0] == '_'
3065 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
3066 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
3068 /* static data member, "_3foo$varname" for example */
3074 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3077 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3080 n
= consume_count (mangled
);
3081 if (n
< 0 || n
> (long) strlen (*mangled
))
3087 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
3088 && (*mangled
)[9] == 'N'
3089 && (*mangled
)[8] == (*mangled
)[10]
3090 && strchr (cplus_markers
, (*mangled
)[8]))
3092 /* A member of the anonymous namespace. There's information
3093 about what identifier or filename it was keyed to, but
3094 it's just there to make the mangled name unique; we just
3096 string_append (declp
, "{anonymous}");
3099 /* Now p points to the marker before the N, so we need to
3100 update it to the first marker after what we consumed. */
3101 p
= strpbrk (*mangled
, cplus_markers
);
3105 string_appendn (declp
, *mangled
, n
);
3108 if (success
&& (p
== *mangled
))
3110 /* Consumed everything up to the cplus_marker, append the
3113 string_append (declp
, SCOPE_STRING (work
));
3114 n
= strlen (*mangled
);
3115 string_appendn (declp
, *mangled
, n
);
3123 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
3128 delta
= consume_count (mangled
);
3133 char *method
= internal_cplus_demangle (work
, ++*mangled
);
3138 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
3139 string_append (declp
, buf
);
3140 string_append (declp
, method
);
3142 n
= strlen (*mangled
);
3151 else if (strncmp (*mangled
, "__t", 3) == 0
3152 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
3154 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
3160 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3163 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3166 success
= do_type (work
, mangled
, declp
);
3169 if (success
&& **mangled
!= '\0')
3172 string_append (declp
, p
);
3182 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
3183 string
*result
, int namelength
)
3185 char * recurse
= (char *)NULL
;
3186 char * recurse_dem
= (char *)NULL
;
3188 recurse
= XNEWVEC (char, namelength
+ 1);
3189 memcpy (recurse
, *mangled
, namelength
);
3190 recurse
[namelength
] = '\000';
3192 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3196 string_append (result
, recurse_dem
);
3201 string_appendn (result
, *mangled
, namelength
);
3204 *mangled
+= namelength
;
3211 arm_special -- special handling of ARM/lucid mangled strings
3216 arm_special (const char **mangled,
3222 Process some special ARM style mangling forms that don't fit
3223 the normal pattern. For example:
3225 __vtbl__3foo (foo virtual table)
3226 __vtbl__3foo__3bar (bar::foo virtual table)
3231 arm_special (const char **mangled
, string
*declp
)
3237 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3239 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3240 and create the decl. Note that we consume the entire mangled
3241 input string, which means that demangle_signature has no work
3243 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3244 while (*scan
!= '\0') /* first check it can be demangled */
3246 n
= consume_count (&scan
);
3249 return (0); /* no good */
3252 if (scan
[0] == '_' && scan
[1] == '_')
3257 (*mangled
) += ARM_VTABLE_STRLEN
;
3258 while (**mangled
!= '\0')
3260 n
= consume_count (mangled
);
3262 || n
> (long) strlen (*mangled
))
3264 string_prependn (declp
, *mangled
, n
);
3266 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3268 string_prepend (declp
, "::");
3272 string_append (declp
, " virtual table");
3285 demangle_qualified -- demangle 'Q' qualified name strings
3290 demangle_qualified (struct work_stuff *, const char *mangled,
3291 string *result, int isfuncname, int append);
3295 Demangle a qualified name, such as "Q25Outer5Inner" which is
3296 the mangled form of "Outer::Inner". The demangled output is
3297 prepended or appended to the result string according to the
3298 state of the append flag.
3300 If isfuncname is nonzero, then the qualified name we are building
3301 is going to be used as a member function name, so if it is a
3302 constructor or destructor function, append an appropriate
3303 constructor or destructor name. I.E. for the above example,
3304 the result for use as a constructor is "Outer::Inner::Inner"
3305 and the result for use as a destructor is "Outer::Inner::~Inner".
3309 Numeric conversion is ASCII dependent (FIXME).
3314 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3315 string
*result
, int isfuncname
, int append
)
3322 int bindex
= register_Btype (work
);
3324 /* We only make use of ISFUNCNAME if the entity is a constructor or
3326 isfuncname
= (isfuncname
3327 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3329 string_init (&temp
);
3330 string_init (&last_name
);
3332 if ((*mangled
)[0] == 'K')
3334 /* Squangling qualified name reuse */
3337 idx
= consume_count_with_underscores (mangled
);
3338 if (idx
== -1 || idx
>= work
-> numk
)
3341 string_append (&temp
, work
-> ktypevec
[idx
]);
3344 switch ((*mangled
)[1])
3347 /* GNU mangled name with more than 9 classes. The count is preceded
3348 by an underscore (to distinguish it from the <= 9 case) and followed
3349 by an underscore. */
3351 qualifiers
= consume_count_with_underscores (mangled
);
3352 if (qualifiers
== -1)
3365 /* The count is in a single digit. */
3366 num
[0] = (*mangled
)[1];
3368 qualifiers
= atoi (num
);
3370 /* If there is an underscore after the digit, skip it. This is
3371 said to be for ARM-qualified names, but the ARM makes no
3372 mention of such an underscore. Perhaps cfront uses one. */
3373 if ((*mangled
)[2] == '_')
3388 /* Pick off the names and collect them in the temp buffer in the order
3389 in which they are found, separated by '::'. */
3391 while (qualifiers
-- > 0)
3394 string_clear (&last_name
);
3396 if (*mangled
[0] == '_')
3399 if (*mangled
[0] == 't')
3401 /* Here we always append to TEMP since we will want to use
3402 the template name without the template parameters as a
3403 constructor or destructor name. The appropriate
3404 (parameter-less) value is returned by demangle_template
3405 in LAST_NAME. We do not remember the template type here,
3406 in order to match the G++ mangling algorithm. */
3407 success
= demangle_template(work
, mangled
, &temp
,
3412 else if (*mangled
[0] == 'K')
3416 idx
= consume_count_with_underscores (mangled
);
3417 if (idx
== -1 || idx
>= work
->numk
)
3420 string_append (&temp
, work
->ktypevec
[idx
]);
3423 if (!success
) break;
3430 /* Now recursively demangle the qualifier
3431 * This is necessary to deal with templates in
3432 * mangling styles like EDG */
3433 namelength
= consume_count (mangled
);
3434 if (namelength
== -1)
3439 recursively_demangle(work
, mangled
, &temp
, namelength
);
3443 string_delete (&last_name
);
3444 success
= do_type (work
, mangled
, &last_name
);
3447 string_appends (&temp
, &last_name
);
3452 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3455 string_append (&temp
, SCOPE_STRING (work
));
3458 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3460 /* If we are using the result as a function name, we need to append
3461 the appropriate '::' separated constructor or destructor name.
3462 We do this here because this is the most convenient place, where
3463 we already have a pointer to the name and the length of the name. */
3467 string_append (&temp
, SCOPE_STRING (work
));
3468 if (work
-> destructor
& 1)
3469 string_append (&temp
, "~");
3470 string_appends (&temp
, &last_name
);
3473 /* Now either prepend the temp buffer to the result, or append it,
3474 depending upon the state of the append flag. */
3477 string_appends (result
, &temp
);
3480 if (!STRING_EMPTY (result
))
3481 string_append (&temp
, SCOPE_STRING (work
));
3482 string_prepends (result
, &temp
);
3485 string_delete (&last_name
);
3486 string_delete (&temp
);
3494 get_count -- convert an ascii count to integer, consuming tokens
3499 get_count (const char **type, int *count)
3503 Assume that *type points at a count in a mangled name; set
3504 *count to its value, and set *type to the next character after
3505 the count. There are some weird rules in effect here.
3507 If *type does not point at a string of digits, return zero.
3509 If *type points at a string of digits followed by an
3510 underscore, set *count to their value as an integer, advance
3511 *type to point *after the underscore, and return 1.
3513 If *type points at a string of digits not followed by an
3514 underscore, consume only the first digit. Set *count to its
3515 value as an integer, leave *type pointing after that digit,
3518 The excuse for this odd behavior: in the ARM and HP demangling
3519 styles, a type can be followed by a repeat count of the form
3522 `x' is a single digit specifying how many additional copies
3523 of the type to append to the argument list, and
3525 `y' is one or more digits, specifying the zero-based index of
3526 the first repeated argument in the list. Yes, as you're
3527 unmangling the name you can figure this out yourself, but
3530 So, for example, in `bar__3fooFPiN51', the first argument is a
3531 pointer to an integer (`Pi'), and then the next five arguments
3532 are the same (`N5'), and the first repeat is the function's
3533 second argument (`1').
3537 get_count (const char **type
, int *count
)
3542 if (!ISDIGIT ((unsigned char)**type
))
3546 *count
= **type
- '0';
3548 if (ISDIGIT ((unsigned char)**type
))
3558 while (ISDIGIT ((unsigned char)*p
));
3569 /* RESULT will be initialised here; it will be freed on failure. The
3570 value returned is really a type_kind_t. */
3573 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3581 const char *remembered_type
;
3583 type_kind_t tk
= tk_none
;
3585 string_init (&decl
);
3586 string_init (result
);
3591 while (success
&& !done
)
3597 /* A pointer type */
3601 if (! (work
-> options
& DMGL_JAVA
))
3602 string_prepend (&decl
, "*");
3607 /* A reference type */
3610 string_prepend (&decl
, "&");
3615 /* An rvalue reference type */
3618 string_prepend (&decl
, "&&");
3620 tk
= tk_rvalue_reference
;
3627 if (!STRING_EMPTY (&decl
)
3628 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3630 string_prepend (&decl
, "(");
3631 string_append (&decl
, ")");
3633 string_append (&decl
, "[");
3634 if (**mangled
!= '_')
3635 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3637 if (**mangled
== '_')
3639 string_append (&decl
, "]");
3643 /* A back reference to a previously seen type */
3646 if (!get_count (mangled
, &n
) || n
< 0 || n
>= work
-> ntypes
)
3651 for (i
= 0; i
< work
->nproctypes
; i
++)
3652 if (work
-> proctypevec
[i
] == n
)
3658 push_processed_type (work
, n
);
3659 remembered_type
= work
->typevec
[n
];
3660 mangled
= &remembered_type
;
3667 if (!STRING_EMPTY (&decl
)
3668 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3670 string_prepend (&decl
, "(");
3671 string_append (&decl
, ")");
3673 /* After picking off the function args, we expect to either find the
3674 function return type (preceded by an '_') or the end of the
3676 if (!demangle_nested_args (work
, mangled
, &decl
)
3677 || (**mangled
!= '_' && **mangled
!= '\0'))
3682 if (success
&& (**mangled
== '_'))
3688 type_quals
= TYPE_UNQUALIFIED
;
3690 member
= **mangled
== 'M';
3693 string_append (&decl
, ")");
3695 /* We don't need to prepend `::' for a qualified name;
3696 demangle_qualified will do that for us. */
3697 if (**mangled
!= 'Q')
3698 string_prepend (&decl
, SCOPE_STRING (work
));
3700 if (ISDIGIT ((unsigned char)**mangled
))
3702 n
= consume_count (mangled
);
3704 || (int) strlen (*mangled
) < n
)
3709 string_prependn (&decl
, *mangled
, n
);
3712 else if (**mangled
== 'X' || **mangled
== 'Y')
3715 do_type (work
, mangled
, &temp
);
3716 string_prepends (&decl
, &temp
);
3717 string_delete (&temp
);
3719 else if (**mangled
== 't')
3722 string_init (&temp
);
3723 success
= demangle_template (work
, mangled
, &temp
,
3727 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3728 string_delete (&temp
);
3732 string_delete (&temp
);
3736 else if (**mangled
== 'Q')
3738 success
= demangle_qualified (work
, mangled
, &decl
,
3750 string_prepend (&decl
, "(");
3758 type_quals
|= code_for_qualifier (**mangled
);
3766 if (*(*mangled
)++ != 'F')
3772 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3773 || **mangled
!= '_')
3779 if (! PRINT_ANSI_QUALIFIERS
)
3783 if (type_quals
!= TYPE_UNQUALIFIED
)
3785 APPEND_BLANK (&decl
);
3786 string_append (&decl
, qualifier_string (type_quals
));
3797 if (PRINT_ANSI_QUALIFIERS
)
3799 if (!STRING_EMPTY (&decl
))
3800 string_prepend (&decl
, " ");
3802 string_prepend (&decl
, demangle_qualifier (**mangled
));
3817 if (success
) switch (**mangled
)
3819 /* A qualified name, such as "Outer::Inner". */
3823 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3827 /* A back reference to a previously seen squangled type */
3830 if (!get_count (mangled
, &n
) || n
< 0 || n
>= work
-> numb
)
3833 string_append (result
, work
->btypevec
[n
]);
3838 /* A template parm. We substitute the corresponding argument. */
3843 idx
= consume_count_with_underscores (mangled
);
3846 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3847 || consume_count_with_underscores (mangled
) == -1)
3853 if (work
->tmpl_argvec
)
3854 string_append (result
, work
->tmpl_argvec
[idx
]);
3856 string_append_template_idx (result
, idx
);
3863 success
= demangle_fund_type (work
, mangled
, result
);
3865 tk
= (type_kind_t
) success
;
3871 if (!STRING_EMPTY (&decl
))
3873 string_append (result
, " ");
3874 string_appends (result
, &decl
);
3878 string_delete (result
);
3879 string_delete (&decl
);
3882 pop_processed_type (work
);
3885 /* Assume an integral type, if we're not sure. */
3886 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3891 /* Given a pointer to a type string that represents a fundamental type
3892 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3893 string in which the demangled output is being built in RESULT, and
3894 the WORK structure, decode the types and add them to the result.
3899 "Sl" => "signed long"
3900 "CUs" => "const unsigned short"
3902 The value returned is really a type_kind_t. */
3905 demangle_fund_type (struct work_stuff
*work
,
3906 const char **mangled
, string
*result
)
3910 char buf
[INTBUF_SIZE
+ 5 /* 'int%u_t' */];
3911 unsigned int dec
= 0;
3912 type_kind_t tk
= tk_integral
;
3914 /* First pick off any type qualifiers. There can be more than one. */
3923 if (PRINT_ANSI_QUALIFIERS
)
3925 if (!STRING_EMPTY (result
))
3926 string_prepend (result
, " ");
3927 string_prepend (result
, demangle_qualifier (**mangled
));
3933 APPEND_BLANK (result
);
3934 string_append (result
, "unsigned");
3936 case 'S': /* signed char only */
3938 APPEND_BLANK (result
);
3939 string_append (result
, "signed");
3943 APPEND_BLANK (result
);
3944 string_append (result
, "__complex");
3952 /* Now pick off the fundamental type. There can be only one. */
3961 APPEND_BLANK (result
);
3962 string_append (result
, "void");
3966 APPEND_BLANK (result
);
3967 string_append (result
, "long long");
3971 APPEND_BLANK (result
);
3972 string_append (result
, "long");
3976 APPEND_BLANK (result
);
3977 string_append (result
, "int");
3981 APPEND_BLANK (result
);
3982 string_append (result
, "short");
3986 APPEND_BLANK (result
);
3987 string_append (result
, "bool");
3992 APPEND_BLANK (result
);
3993 string_append (result
, "char");
3998 APPEND_BLANK (result
);
3999 string_append (result
, "wchar_t");
4004 APPEND_BLANK (result
);
4005 string_append (result
, "long double");
4010 APPEND_BLANK (result
);
4011 string_append (result
, "double");
4016 APPEND_BLANK (result
);
4017 string_append (result
, "float");
4022 if (!ISDIGIT ((unsigned char)**mangled
))
4029 if (**mangled
== '_')
4034 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
4037 if (**mangled
!= '_')
4047 strncpy (buf
, *mangled
, 2);
4049 *mangled
+= min (strlen (*mangled
), 2);
4051 sscanf (buf
, "%x", &dec
);
4052 sprintf (buf
, "int%u_t", dec
);
4053 APPEND_BLANK (result
);
4054 string_append (result
, buf
);
4058 /* An explicit type, such as "6mytype" or "7integer" */
4070 int bindex
= register_Btype (work
);
4072 string_init (&btype
);
4073 if (demangle_class_name (work
, mangled
, &btype
)) {
4074 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
4075 APPEND_BLANK (result
);
4076 string_appends (result
, &btype
);
4080 string_delete (&btype
);
4086 string_init (&btype
);
4087 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
4088 string_appends (result
, &btype
);
4089 string_delete (&btype
);
4097 return success
? ((int) tk
) : 0;
4101 /* Handle a template's value parameter for HP aCC (extension from ARM)
4102 **mangled points to 'S' or 'U' */
4105 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
4106 const char **mangled
, string
*result
)
4110 if (**mangled
!= 'U' && **mangled
!= 'S')
4113 unsigned_const
= (**mangled
== 'U');
4120 string_append (result
, "-");
4126 /* special case for -2^31 */
4127 string_append (result
, "-2147483648");
4134 /* We have to be looking at an integer now */
4135 if (!(ISDIGIT ((unsigned char)**mangled
)))
4138 /* We only deal with integral values for template
4139 parameters -- so it's OK to look only for digits */
4140 while (ISDIGIT ((unsigned char)**mangled
))
4142 char_str
[0] = **mangled
;
4143 string_append (result
, char_str
);
4148 string_append (result
, "U");
4150 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4151 with L or LL suffixes. pai/1997-09-03 */
4153 return 1; /* success */
4156 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4157 **mangled is pointing to the 'A' */
4160 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
4163 int literal_len
= 0;
4167 if (**mangled
!= 'A')
4172 literal_len
= consume_count (mangled
);
4174 if (literal_len
<= 0
4175 || literal_len
> (long) strlen (*mangled
))
4178 /* Literal parameters are names of arrays, functions, etc. and the
4179 canonical representation uses the address operator */
4180 string_append (result
, "&");
4182 /* Now recursively demangle the literal name */
4183 recurse
= XNEWVEC (char, literal_len
+ 1);
4184 memcpy (recurse
, *mangled
, literal_len
);
4185 recurse
[literal_len
] = '\000';
4187 recurse_dem
= cplus_demangle (recurse
, work
->options
);
4191 string_append (result
, recurse_dem
);
4196 string_appendn (result
, *mangled
, literal_len
);
4198 (*mangled
) += literal_len
;
4205 snarf_numeric_literal (const char **args
, string
*arg
)
4210 string_append (arg
, char_str
);
4213 else if (**args
== '+')
4216 if (!ISDIGIT ((unsigned char)**args
))
4219 while (ISDIGIT ((unsigned char)**args
))
4221 char_str
[0] = **args
;
4222 string_append (arg
, char_str
);
4229 /* Demangle the next argument, given by MANGLED into RESULT, which
4230 *should be an uninitialized* string. It will be initialized here,
4231 and free'd should anything go wrong. */
4234 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4236 /* Remember where we started so that we can record the type, for
4237 non-squangling type remembering. */
4238 const char *start
= *mangled
;
4240 string_init (result
);
4242 if (work
->nrepeats
> 0)
4246 if (work
->previous_argument
== 0)
4249 /* We want to reissue the previous type in this argument list. */
4250 string_appends (result
, work
->previous_argument
);
4254 if (**mangled
== 'n')
4256 /* A squangling-style repeat. */
4258 work
->nrepeats
= consume_count(mangled
);
4260 if (work
->nrepeats
<= 0)
4261 /* This was not a repeat count after all. */
4264 if (work
->nrepeats
> 9)
4266 if (**mangled
!= '_')
4267 /* The repeat count should be followed by an '_' in this
4274 /* Now, the repeat is all set up. */
4275 return do_arg (work
, mangled
, result
);
4278 /* Save the result in WORK->previous_argument so that we can find it
4279 if it's repeated. Note that saving START is not good enough: we
4280 do not want to add additional types to the back-referenceable
4281 type vector when processing a repeated type. */
4282 if (work
->previous_argument
)
4283 string_delete (work
->previous_argument
);
4285 work
->previous_argument
= XNEW (string
);
4287 if (!do_type (work
, mangled
, work
->previous_argument
))
4290 string_appends (result
, work
->previous_argument
);
4292 remember_type (work
, start
, *mangled
- start
);
4297 push_processed_type (struct work_stuff
*work
, int typevec_index
)
4299 if (work
->nproctypes
>= work
->proctypevec_size
)
4301 if (!work
->proctypevec_size
)
4303 work
->proctypevec_size
= 4;
4304 work
->proctypevec
= XNEWVEC (int, work
->proctypevec_size
);
4308 if (work
->proctypevec_size
< 16)
4309 /* Double when small. */
4310 work
->proctypevec_size
*= 2;
4313 /* Grow slower when large. */
4314 if (work
->proctypevec_size
> (INT_MAX
/ 3) * 2)
4315 xmalloc_failed (INT_MAX
);
4316 work
->proctypevec_size
= (work
->proctypevec_size
* 3 / 2);
4319 = XRESIZEVEC (int, work
->proctypevec
, work
->proctypevec_size
);
4322 work
->proctypevec
[work
->nproctypes
++] = typevec_index
;
4326 pop_processed_type (struct work_stuff
*work
)
4332 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4336 if (work
->forgetting_types
)
4339 if (work
-> ntypes
>= work
-> typevec_size
)
4341 if (work
-> typevec_size
== 0)
4343 work
-> typevec_size
= 3;
4344 work
-> typevec
= XNEWVEC (char *, work
->typevec_size
);
4348 if (work
-> typevec_size
> INT_MAX
/ 2)
4349 xmalloc_failed (INT_MAX
);
4350 work
-> typevec_size
*= 2;
4352 = XRESIZEVEC (char *, work
->typevec
, work
->typevec_size
);
4355 tem
= XNEWVEC (char, len
+ 1);
4356 memcpy (tem
, start
, len
);
4358 work
-> typevec
[work
-> ntypes
++] = tem
;
4362 /* Remember a K type class qualifier. */
4364 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4368 if (work
-> numk
>= work
-> ksize
)
4370 if (work
-> ksize
== 0)
4373 work
-> ktypevec
= XNEWVEC (char *, work
->ksize
);
4377 if (work
-> ksize
> INT_MAX
/ 2)
4378 xmalloc_failed (INT_MAX
);
4381 = XRESIZEVEC (char *, work
->ktypevec
, work
->ksize
);
4384 tem
= XNEWVEC (char, len
+ 1);
4385 memcpy (tem
, start
, len
);
4387 work
-> ktypevec
[work
-> numk
++] = tem
;
4390 /* Register a B code, and get an index for it. B codes are registered
4391 as they are seen, rather than as they are completed, so map<temp<char> >
4392 registers map<temp<char> > as B0, and temp<char> as B1 */
4395 register_Btype (struct work_stuff
*work
)
4399 if (work
-> numb
>= work
-> bsize
)
4401 if (work
-> bsize
== 0)
4404 work
-> btypevec
= XNEWVEC (char *, work
->bsize
);
4408 if (work
-> bsize
> INT_MAX
/ 2)
4409 xmalloc_failed (INT_MAX
);
4412 = XRESIZEVEC (char *, work
->btypevec
, work
->bsize
);
4415 ret
= work
-> numb
++;
4416 work
-> btypevec
[ret
] = NULL
;
4420 /* Store a value into a previously registered B code type. */
4423 remember_Btype (struct work_stuff
*work
, const char *start
,
4428 tem
= XNEWVEC (char, len
+ 1);
4429 memcpy (tem
, start
, len
);
4431 work
-> btypevec
[index
] = tem
;
4434 /* Lose all the info related to B and K type codes. */
4436 forget_B_and_K_types (struct work_stuff
*work
)
4440 while (work
-> numk
> 0)
4442 i
= --(work
-> numk
);
4443 if (work
-> ktypevec
[i
] != NULL
)
4445 free (work
-> ktypevec
[i
]);
4446 work
-> ktypevec
[i
] = NULL
;
4450 while (work
-> numb
> 0)
4452 i
= --(work
-> numb
);
4453 if (work
-> btypevec
[i
] != NULL
)
4455 free (work
-> btypevec
[i
]);
4456 work
-> btypevec
[i
] = NULL
;
4460 /* Forget the remembered types, but not the type vector itself. */
4463 forget_types (struct work_stuff
*work
)
4467 while (work
-> ntypes
> 0)
4469 i
= --(work
-> ntypes
);
4470 if (work
-> typevec
[i
] != NULL
)
4472 free (work
-> typevec
[i
]);
4473 work
-> typevec
[i
] = NULL
;
4478 /* Process the argument list part of the signature, after any class spec
4479 has been consumed, as well as the first 'F' character (if any). For
4482 "__als__3fooRT0" => process "RT0"
4483 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4485 DECLP must be already initialised, usually non-empty. It won't be freed
4488 Note that g++ differs significantly from ARM and lucid style mangling
4489 with regards to references to previously seen types. For example, given
4490 the source fragment:
4494 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4497 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4498 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4500 g++ produces the names:
4505 while lcc (and presumably other ARM style compilers as well) produces:
4507 foo__FiR3fooT1T2T1T2
4508 __ct__3fooFiR3fooT1T2T1T2
4510 Note that g++ bases its type numbers starting at zero and counts all
4511 previously seen types, while lucid/ARM bases its type numbers starting
4512 at one and only considers types after it has seen the 'F' character
4513 indicating the start of the function args. For lucid/ARM style, we
4514 account for this difference by discarding any previously seen types when
4515 we see the 'F' character, and subtracting one from the type number
4521 demangle_args (struct work_stuff
*work
, const char **mangled
,
4531 if (PRINT_ARG_TYPES
)
4533 string_append (declp
, "(");
4534 if (**mangled
== '\0')
4536 string_append (declp
, "void");
4540 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4541 || work
->nrepeats
> 0)
4543 if ((**mangled
== 'N') || (**mangled
== 'T'))
4545 temptype
= *(*mangled
)++;
4547 if (temptype
== 'N')
4549 if (!get_count (mangled
, &r
))
4558 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4560 /* If we have 10 or more types we might have more than a 1 digit
4561 index so we'll have to consume the whole count here. This
4562 will lose if the next thing is a type name preceded by a
4563 count but it's impossible to demangle that case properly
4564 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4565 Pc, ...)" or "(..., type12, char *, ...)" */
4566 if ((t
= consume_count(mangled
)) <= 0)
4573 if (!get_count (mangled
, &t
))
4578 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4582 /* Validate the type index. Protect against illegal indices from
4583 malformed type strings. */
4584 if ((t
< 0) || (t
>= work
-> ntypes
))
4588 while (work
->nrepeats
> 0 || --r
>= 0)
4590 tem
= work
-> typevec
[t
];
4591 if (need_comma
&& PRINT_ARG_TYPES
)
4593 string_append (declp
, ", ");
4595 push_processed_type (work
, t
);
4596 if (!do_arg (work
, &tem
, &arg
))
4598 pop_processed_type (work
);
4601 pop_processed_type (work
);
4602 if (PRINT_ARG_TYPES
)
4604 string_appends (declp
, &arg
);
4606 string_delete (&arg
);
4612 if (need_comma
&& PRINT_ARG_TYPES
)
4613 string_append (declp
, ", ");
4614 if (!do_arg (work
, mangled
, &arg
))
4616 if (PRINT_ARG_TYPES
)
4617 string_appends (declp
, &arg
);
4618 string_delete (&arg
);
4623 if (**mangled
== 'e')
4626 if (PRINT_ARG_TYPES
)
4630 string_append (declp
, ",");
4632 string_append (declp
, "...");
4636 if (PRINT_ARG_TYPES
)
4638 string_append (declp
, ")");
4643 /* Like demangle_args, but for demangling the argument lists of function
4644 and method pointers or references, not top-level declarations. */
4647 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4650 string
* saved_previous_argument
;
4654 /* The G++ name-mangling algorithm does not remember types on nested
4655 argument lists, unless -fsquangling is used, and in that case the
4656 type vector updated by remember_type is not used. So, we turn
4657 off remembering of types here. */
4658 ++work
->forgetting_types
;
4660 /* For the repeat codes used with -fsquangling, we must keep track of
4661 the last argument. */
4662 saved_previous_argument
= work
->previous_argument
;
4663 saved_nrepeats
= work
->nrepeats
;
4664 work
->previous_argument
= 0;
4667 /* Actually demangle the arguments. */
4668 result
= demangle_args (work
, mangled
, declp
);
4670 /* Restore the previous_argument field. */
4671 if (work
->previous_argument
)
4673 string_delete (work
->previous_argument
);
4674 free ((char *) work
->previous_argument
);
4676 work
->previous_argument
= saved_previous_argument
;
4677 --work
->forgetting_types
;
4678 work
->nrepeats
= saved_nrepeats
;
4683 /* Returns 1 if a valid function name was found or 0 otherwise. */
4686 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4687 string
*declp
, const char *scan
)
4693 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4694 string_need (declp
, 1);
4695 *(declp
-> p
) = '\0';
4697 /* Consume the function name, including the "__" separating the name
4698 from the signature. We are guaranteed that SCAN points to the
4701 (*mangled
) = scan
+ 2;
4702 /* We may be looking at an instantiation of a template function:
4703 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4704 following _F marks the start of the function arguments. Handle
4705 the template arguments first. */
4707 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4709 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4710 /* This leaves MANGLED pointing to the 'F' marking func args */
4713 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4716 /* See if we have an ARM style constructor or destructor operator.
4717 If so, then just record it, clear the decl, and return.
4718 We can't build the actual constructor/destructor decl until later,
4719 when we recover the class name from the signature. */
4721 if (strcmp (declp
-> b
, "__ct") == 0)
4723 work
-> constructor
+= 1;
4724 string_clear (declp
);
4727 else if (strcmp (declp
-> b
, "__dt") == 0)
4729 work
-> destructor
+= 1;
4730 string_clear (declp
);
4735 if (declp
->p
- declp
->b
>= 3
4736 && declp
->b
[0] == 'o'
4737 && declp
->b
[1] == 'p'
4738 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4740 /* see if it's an assignment expression */
4741 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4742 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4744 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4746 int len
= declp
->p
- declp
->b
- 10;
4747 if ((int) strlen (optable
[i
].in
) == len
4748 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4750 string_clear (declp
);
4751 string_append (declp
, "operator");
4752 string_append (declp
, optable
[i
].out
);
4753 string_append (declp
, "=");
4760 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4762 int len
= declp
->p
- declp
->b
- 3;
4763 if ((int) strlen (optable
[i
].in
) == len
4764 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4766 string_clear (declp
);
4767 string_append (declp
, "operator");
4768 string_append (declp
, optable
[i
].out
);
4774 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4775 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4777 /* type conversion operator */
4779 if (do_type (work
, &tem
, &type
))
4781 string_clear (declp
);
4782 string_append (declp
, "operator ");
4783 string_appends (declp
, &type
);
4784 string_delete (&type
);
4787 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4788 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4791 /* type conversion operator. */
4793 if (do_type (work
, &tem
, &type
))
4795 string_clear (declp
);
4796 string_append (declp
, "operator ");
4797 string_appends (declp
, &type
);
4798 string_delete (&type
);
4801 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4802 && ISLOWER((unsigned char)declp
->b
[2])
4803 && ISLOWER((unsigned char)declp
->b
[3]))
4805 if (declp
->b
[4] == '\0')
4808 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4810 if (strlen (optable
[i
].in
) == 2
4811 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4813 string_clear (declp
);
4814 string_append (declp
, "operator");
4815 string_append (declp
, optable
[i
].out
);
4822 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4825 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4827 if (strlen (optable
[i
].in
) == 3
4828 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4830 string_clear (declp
);
4831 string_append (declp
, "operator");
4832 string_append (declp
, optable
[i
].out
);
4840 /* If a function name was obtained but it's not valid, we were not
4842 if (LEN_STRING (declp
) == 1 && declp
->b
[0] == '.')
4848 /* a mini string-handling package */
4851 string_need (string
*s
, int n
)
4861 s
->p
= s
->b
= XNEWVEC (char, n
);
4864 else if (s
->e
- s
->p
< n
)
4867 if (n
> INT_MAX
/ 2 - tem
)
4868 xmalloc_failed (INT_MAX
);
4871 s
->b
= XRESIZEVEC (char, s
->b
, n
);
4878 string_delete (string
*s
)
4883 s
->b
= s
->e
= s
->p
= NULL
;
4888 string_init (string
*s
)
4890 s
->b
= s
->p
= s
->e
= NULL
;
4894 string_clear (string
*s
)
4902 string_empty (string
*s
)
4904 return (s
->b
== s
->p
);
4910 string_append (string
*p
, const char *s
)
4913 if (s
== NULL
|| *s
== '\0')
4917 memcpy (p
->p
, s
, n
);
4922 string_appends (string
*p
, string
*s
)
4930 memcpy (p
->p
, s
->b
, n
);
4936 string_appendn (string
*p
, const char *s
, int n
)
4941 memcpy (p
->p
, s
, n
);
4947 string_prepend (string
*p
, const char *s
)
4949 if (s
!= NULL
&& *s
!= '\0')
4951 string_prependn (p
, s
, strlen (s
));
4956 string_prepends (string
*p
, string
*s
)
4960 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4965 string_prependn (string
*p
, const char *s
, int n
)
4972 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4976 memcpy (p
->b
, s
, n
);
4982 string_append_template_idx (string
*s
, int idx
)
4984 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4985 sprintf(buf
, "T%d", idx
);
4986 string_append (s
, buf
);