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
149 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
150 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
152 static const struct optable
154 const char *const in
;
155 const char *const out
;
158 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
159 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
160 {"new", " new", 0}, /* old (1.91, and 1.x) */
161 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
162 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
163 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
164 {"as", "=", DMGL_ANSI
}, /* ansi */
165 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
166 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
167 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
168 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
169 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
170 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
171 {"plus", "+", 0}, /* old */
172 {"pl", "+", DMGL_ANSI
}, /* ansi */
173 {"apl", "+=", DMGL_ANSI
}, /* ansi */
174 {"minus", "-", 0}, /* old */
175 {"mi", "-", DMGL_ANSI
}, /* ansi */
176 {"ami", "-=", DMGL_ANSI
}, /* ansi */
177 {"mult", "*", 0}, /* old */
178 {"ml", "*", DMGL_ANSI
}, /* ansi */
179 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
180 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
181 {"convert", "+", 0}, /* old (unary +) */
182 {"negate", "-", 0}, /* old (unary -) */
183 {"trunc_mod", "%", 0}, /* old */
184 {"md", "%", DMGL_ANSI
}, /* ansi */
185 {"amd", "%=", DMGL_ANSI
}, /* ansi */
186 {"trunc_div", "/", 0}, /* old */
187 {"dv", "/", DMGL_ANSI
}, /* ansi */
188 {"adv", "/=", DMGL_ANSI
}, /* ansi */
189 {"truth_andif", "&&", 0}, /* old */
190 {"aa", "&&", DMGL_ANSI
}, /* ansi */
191 {"truth_orif", "||", 0}, /* old */
192 {"oo", "||", DMGL_ANSI
}, /* ansi */
193 {"truth_not", "!", 0}, /* old */
194 {"nt", "!", DMGL_ANSI
}, /* ansi */
195 {"postincrement","++", 0}, /* old */
196 {"pp", "++", DMGL_ANSI
}, /* ansi */
197 {"postdecrement","--", 0}, /* old */
198 {"mm", "--", DMGL_ANSI
}, /* ansi */
199 {"bit_ior", "|", 0}, /* old */
200 {"or", "|", DMGL_ANSI
}, /* ansi */
201 {"aor", "|=", DMGL_ANSI
}, /* ansi */
202 {"bit_xor", "^", 0}, /* old */
203 {"er", "^", DMGL_ANSI
}, /* ansi */
204 {"aer", "^=", DMGL_ANSI
}, /* ansi */
205 {"bit_and", "&", 0}, /* old */
206 {"ad", "&", DMGL_ANSI
}, /* ansi */
207 {"aad", "&=", DMGL_ANSI
}, /* ansi */
208 {"bit_not", "~", 0}, /* old */
209 {"co", "~", DMGL_ANSI
}, /* ansi */
210 {"call", "()", 0}, /* old */
211 {"cl", "()", DMGL_ANSI
}, /* ansi */
212 {"alshift", "<<", 0}, /* old */
213 {"ls", "<<", DMGL_ANSI
}, /* ansi */
214 {"als", "<<=", DMGL_ANSI
}, /* ansi */
215 {"arshift", ">>", 0}, /* old */
216 {"rs", ">>", DMGL_ANSI
}, /* ansi */
217 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
218 {"component", "->", 0}, /* old */
219 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
220 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
221 {"indirect", "*", 0}, /* old */
222 {"method_call", "->()", 0}, /* old */
223 {"addr", "&", 0}, /* old (unary &) */
224 {"array", "[]", 0}, /* old */
225 {"vc", "[]", DMGL_ANSI
}, /* ansi */
226 {"compound", ", ", 0}, /* old */
227 {"cm", ", ", DMGL_ANSI
}, /* ansi */
228 {"cond", "?:", 0}, /* old */
229 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
230 {"max", ">?", 0}, /* old */
231 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
232 {"min", "<?", 0}, /* old */
233 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
234 {"nop", "", 0}, /* old (for operator=) */
235 {"rm", "->*", DMGL_ANSI
}, /* ansi */
236 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
239 /* These values are used to indicate the various type varieties.
240 They are all non-zero so that they can be used as `success'
242 typedef enum type_kind_t
253 const struct demangler_engine libiberty_demanglers
[] =
256 NO_DEMANGLING_STYLE_STRING
,
258 "Demangling disabled"
262 AUTO_DEMANGLING_STYLE_STRING
,
264 "Automatic selection based on executable"
268 GNU_DEMANGLING_STYLE_STRING
,
270 "GNU (g++) style demangling"
274 LUCID_DEMANGLING_STYLE_STRING
,
276 "Lucid (lcc) style demangling"
280 ARM_DEMANGLING_STYLE_STRING
,
282 "ARM style demangling"
286 HP_DEMANGLING_STYLE_STRING
,
288 "HP (aCC) style demangling"
292 EDG_DEMANGLING_STYLE_STRING
,
294 "EDG style demangling"
298 GNU_V3_DEMANGLING_STYLE_STRING
,
300 "GNU (g++) V3 ABI-style demangling"
304 JAVA_DEMANGLING_STYLE_STRING
,
306 "Java style demangling"
310 GNAT_DEMANGLING_STYLE_STRING
,
312 "GNAT style demangling"
316 DLANG_DEMANGLING_STYLE_STRING
,
318 "DLANG style demangling"
322 NULL
, unknown_demangling
, NULL
326 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
327 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
328 string_append(str, " ");}
329 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
331 /* The scope separator appropriate for the language being demangled. */
333 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
335 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
336 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
338 /* Prototypes for local functions */
340 static void delete_work_stuff (struct work_stuff
*);
342 static void delete_non_B_K_work_stuff (struct work_stuff
*);
344 static char *mop_up (struct work_stuff
*, string
*, int);
346 static void squangle_mop_up (struct work_stuff
*);
348 static void work_stuff_copy_to_from (struct work_stuff
*, struct work_stuff
*);
352 demangle_method_args (struct work_stuff
*, const char **, string
*);
356 internal_cplus_demangle (struct work_stuff
*, const char *);
359 demangle_template_template_parm (struct work_stuff
*work
,
360 const char **, string
*);
363 demangle_template (struct work_stuff
*work
, const char **, string
*,
367 arm_pt (struct work_stuff
*, const char *, int, const char **,
371 demangle_class_name (struct work_stuff
*, const char **, string
*);
374 demangle_qualified (struct work_stuff
*, const char **, string
*,
377 static int demangle_class (struct work_stuff
*, const char **, string
*);
379 static int demangle_fund_type (struct work_stuff
*, const char **, string
*);
381 static int demangle_signature (struct work_stuff
*, const char **, string
*);
383 static int demangle_prefix (struct work_stuff
*, const char **, string
*);
385 static int gnu_special (struct work_stuff
*, const char **, string
*);
387 static int arm_special (const char **, string
*);
389 static void string_need (string
*, int);
391 static void string_delete (string
*);
394 string_init (string
*);
396 static void string_clear (string
*);
399 static int string_empty (string
*);
402 static void string_append (string
*, const char *);
404 static void string_appends (string
*, string
*);
406 static void string_appendn (string
*, const char *, int);
408 static void string_prepend (string
*, const char *);
410 static void string_prependn (string
*, const char *, int);
412 static void string_append_template_idx (string
*, int);
414 static int get_count (const char **, int *);
416 static int consume_count (const char **);
418 static int consume_count_with_underscores (const char**);
420 static int demangle_args (struct work_stuff
*, const char **, string
*);
422 static int demangle_nested_args (struct work_stuff
*, const char**, string
*);
424 static int do_type (struct work_stuff
*, const char **, string
*);
426 static int do_arg (struct work_stuff
*, const char **, string
*);
429 demangle_function_name (struct work_stuff
*, const char **, string
*,
433 iterate_demangle_function (struct work_stuff
*,
434 const char **, string
*, const char *);
436 static void remember_type (struct work_stuff
*, const char *, int);
438 static void remember_Btype (struct work_stuff
*, const char *, int, int);
440 static int register_Btype (struct work_stuff
*);
442 static void remember_Ktype (struct work_stuff
*, const char *, int);
444 static void forget_types (struct work_stuff
*);
446 static void forget_B_and_K_types (struct work_stuff
*);
448 static void string_prepends (string
*, string
*);
451 demangle_template_value_parm (struct work_stuff
*, const char**,
452 string
*, type_kind_t
);
455 do_hpacc_template_const_value (struct work_stuff
*, const char **, string
*);
458 do_hpacc_template_literal (struct work_stuff
*, const char **, string
*);
460 static int snarf_numeric_literal (const char **, string
*);
462 /* There is a TYPE_QUAL value for each type qualifier. They can be
463 combined by bitwise-or to form the complete set of qualifiers for a
466 #define TYPE_UNQUALIFIED 0x0
467 #define TYPE_QUAL_CONST 0x1
468 #define TYPE_QUAL_VOLATILE 0x2
469 #define TYPE_QUAL_RESTRICT 0x4
471 static int code_for_qualifier (int);
473 static const char* qualifier_string (int);
475 static const char* demangle_qualifier (int);
477 static int demangle_expression (struct work_stuff
*, const char **, string
*,
481 demangle_integral_value (struct work_stuff
*, const char **, string
*);
484 demangle_real_value (struct work_stuff
*, const char **, string
*);
487 demangle_arm_hp_template (struct work_stuff
*, const char **, int, string
*);
490 recursively_demangle (struct work_stuff
*, const char **, string
*, int);
492 /* Translate count to integer, consuming tokens in the process.
493 Conversion terminates on the first non-digit character.
495 Trying to consume something that isn't a count results in no
496 consumption of input and a return of -1.
498 Overflow consumes the rest of the digits, and returns -1. */
501 consume_count (const char **type
)
505 if (! ISDIGIT ((unsigned char)**type
))
508 while (ISDIGIT ((unsigned char)**type
))
512 /* Check for overflow.
513 We assume that count is represented using two's-complement;
514 no power of two is divisible by ten, so if an overflow occurs
515 when multiplying by ten, the result will not be a multiple of
517 if ((count
% 10) != 0)
519 while (ISDIGIT ((unsigned char) **type
))
524 count
+= **type
- '0';
535 /* Like consume_count, but for counts that are preceded and followed
536 by '_' if they are greater than 10. Also, -1 is returned for
537 failure, since 0 can be a valid value. */
540 consume_count_with_underscores (const char **mangled
)
544 if (**mangled
== '_')
547 if (!ISDIGIT ((unsigned char)**mangled
))
550 idx
= consume_count (mangled
);
551 if (**mangled
!= '_')
552 /* The trailing underscore was missing. */
559 if (**mangled
< '0' || **mangled
> '9')
562 idx
= **mangled
- '0';
569 /* C is the code for a type-qualifier. Return the TYPE_QUAL
570 corresponding to this qualifier. */
573 code_for_qualifier (int c
)
578 return TYPE_QUAL_CONST
;
581 return TYPE_QUAL_VOLATILE
;
584 return TYPE_QUAL_RESTRICT
;
590 /* C was an invalid qualifier. */
594 /* Return the string corresponding to the qualifiers given by
598 qualifier_string (int type_quals
)
602 case TYPE_UNQUALIFIED
:
605 case TYPE_QUAL_CONST
:
608 case TYPE_QUAL_VOLATILE
:
611 case TYPE_QUAL_RESTRICT
:
614 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
615 return "const volatile";
617 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
618 return "const __restrict";
620 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
621 return "volatile __restrict";
623 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
624 return "const volatile __restrict";
630 /* TYPE_QUALS was an invalid qualifier set. */
634 /* C is the code for a type-qualifier. Return the string
635 corresponding to this qualifier. This function should only be
636 called with a valid qualifier code. */
639 demangle_qualifier (int c
)
641 return qualifier_string (code_for_qualifier (c
));
645 cplus_demangle_opname (const char *opname
, char *result
, int options
)
649 struct work_stuff work
[1];
652 len
= strlen(opname
);
655 memset ((char *) work
, 0, sizeof (work
));
656 work
->options
= options
;
658 if (opname
[0] == '_' && opname
[1] == '_'
659 && opname
[2] == 'o' && opname
[3] == 'p')
662 /* type conversion operator. */
664 if (do_type (work
, &tem
, &type
))
666 strcat (result
, "operator ");
667 strncat (result
, type
.b
, type
.p
- type
.b
);
668 string_delete (&type
);
672 else if (opname
[0] == '_' && opname
[1] == '_'
673 && ISLOWER((unsigned char)opname
[2])
674 && ISLOWER((unsigned char)opname
[3]))
676 if (opname
[4] == '\0')
680 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
682 if (strlen (optable
[i
].in
) == 2
683 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
685 strcat (result
, "operator");
686 strcat (result
, optable
[i
].out
);
694 if (opname
[2] == 'a' && opname
[5] == '\0')
698 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
700 if (strlen (optable
[i
].in
) == 3
701 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
703 strcat (result
, "operator");
704 strcat (result
, optable
[i
].out
);
715 && strchr (cplus_markers
, opname
[2]) != NULL
)
717 /* see if it's an assignment expression */
718 if (len
>= 10 /* op$assign_ */
719 && memcmp (opname
+ 3, "assign_", 7) == 0)
722 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
725 if ((int) strlen (optable
[i
].in
) == len1
726 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
728 strcat (result
, "operator");
729 strcat (result
, optable
[i
].out
);
730 strcat (result
, "=");
739 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
742 if ((int) strlen (optable
[i
].in
) == len1
743 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
745 strcat (result
, "operator");
746 strcat (result
, optable
[i
].out
);
753 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
754 && strchr (cplus_markers
, opname
[4]) != NULL
)
756 /* type conversion operator */
758 if (do_type (work
, &tem
, &type
))
760 strcat (result
, "operator ");
761 strncat (result
, type
.b
, type
.p
- type
.b
);
762 string_delete (&type
);
766 squangle_mop_up (work
);
771 /* Takes operator name as e.g. "++" and returns mangled
772 operator name (e.g. "postincrement_expr"), or NULL if not found.
774 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
775 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
778 cplus_mangle_opname (const char *opname
, int options
)
783 len
= strlen (opname
);
784 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
786 if ((int) strlen (optable
[i
].out
) == len
787 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
788 && memcmp (optable
[i
].out
, opname
, len
) == 0)
789 return optable
[i
].in
;
794 /* Add a routine to set the demangling style to be sure it is valid and
795 allow for any demangler initialization that maybe necessary. */
797 enum demangling_styles
798 cplus_demangle_set_style (enum demangling_styles style
)
800 const struct demangler_engine
*demangler
= libiberty_demanglers
;
802 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
803 if (style
== demangler
->demangling_style
)
805 current_demangling_style
= style
;
806 return current_demangling_style
;
809 return unknown_demangling
;
812 /* Do string name to style translation */
814 enum demangling_styles
815 cplus_demangle_name_to_style (const char *name
)
817 const struct demangler_engine
*demangler
= libiberty_demanglers
;
819 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
820 if (strcmp (name
, demangler
->demangling_style_name
) == 0)
821 return demangler
->demangling_style
;
823 return unknown_demangling
;
826 /* char *cplus_demangle (const char *mangled, int options)
828 If MANGLED is a mangled function name produced by GNU C++, then
829 a pointer to a @code{malloc}ed string giving a C++ representation
830 of the name will be returned; otherwise NULL will be returned.
831 It is the caller's responsibility to free the string which
834 The OPTIONS arg may contain one or more of the following bits:
836 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
838 DMGL_PARAMS Function parameters are included.
842 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
843 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
844 cplus_demangle ("foo__1Ai", 0) => "A::foo"
846 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
847 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
848 cplus_demangle ("foo__1Afe", 0) => "A::foo"
850 Note that any leading underscores, or other such characters prepended by
851 the compilation system, are presumed to have already been stripped from
855 cplus_demangle (const char *mangled
, int options
)
858 struct work_stuff work
[1];
860 if (current_demangling_style
== no_demangling
)
861 return xstrdup (mangled
);
863 memset ((char *) work
, 0, sizeof (work
));
864 work
->options
= options
;
865 if ((work
->options
& DMGL_STYLE_MASK
) == 0)
866 work
->options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
868 /* The V3 ABI demangling is implemented elsewhere. */
869 if (GNU_V3_DEMANGLING
|| AUTO_DEMANGLING
)
871 ret
= cplus_demangle_v3 (mangled
, work
->options
);
872 if (ret
|| GNU_V3_DEMANGLING
)
878 ret
= java_demangle_v3 (mangled
);
884 return ada_demangle (mangled
, options
);
886 if (DLANG_DEMANGLING
)
888 ret
= dlang_demangle (mangled
, options
);
893 ret
= internal_cplus_demangle (work
, mangled
);
894 squangle_mop_up (work
);
898 /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
901 ada_demangle (const char *mangled
, int option ATTRIBUTE_UNUSED
)
908 /* Discard leading _ada_, which is used for library level subprograms. */
909 if (strncmp (mangled
, "_ada_", 5) == 0)
912 /* All ada unit names are lower-case. */
913 if (!ISLOWER (mangled
[0]))
916 /* Most of the demangling will trivially remove chars. Operator names
917 may add one char but because they are always preceeded by '__' which is
918 replaced by '.', they eventually never expand the size.
919 A few special names such as '___elabs' add a few chars (at most 7), but
920 they occur only once. */
921 len0
= strlen (mangled
) + 7 + 1;
922 demangled
= XNEWVEC (char, len0
);
928 /* An entity names is expected. */
931 /* An identifier, which is always lower case. */
934 while (ISLOWER(*p
) || ISDIGIT (*p
)
935 || (p
[0] == '_' && (ISLOWER (p
[1]) || ISDIGIT (p
[1]))));
937 else if (p
[0] == 'O')
939 /* An operator name. */
940 static const char * const operators
[][2] =
941 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
942 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
943 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
944 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
945 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
946 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
947 {"Oexpon", "**"}, {NULL
, NULL
}};
950 for (k
= 0; operators
[k
][0] != NULL
; k
++)
952 size_t slen
= strlen (operators
[k
][0]);
953 if (strncmp (p
, operators
[k
][0], slen
) == 0)
956 slen
= strlen (operators
[k
][1]);
958 memcpy (d
, operators
[k
][1], slen
);
964 /* Operator not found. */
965 if (operators
[k
][0] == NULL
)
970 /* Not a GNAT encoding. */
974 /* The name can be directly followed by some uppercase letters. */
975 if (p
[0] == 'T' && p
[1] == 'K')
978 if (p
[2] == 'B' && p
[3] == 0)
980 /* Subprogram for task body. */
983 else if (p
[2] == '_' && p
[3] == '_')
985 /* Inner declarations in a task. */
993 if (p
[0] == 'E' && p
[1] == 0)
995 /* Exception name. */
998 if ((p
[0] == 'P' || p
[0] == 'N') && p
[1] == 0)
1000 /* Protected type subprogram. */
1003 if ((*p
== 'N' || *p
== 'S') && p
[1] == 0)
1005 /* Enumerated type name table. */
1012 while (p
[0] == 'n' || p
[0] == 'b')
1015 if (p
[0] == 'S' && p
[1] != 0 && (p
[2] == '_' || p
[2] == 0))
1017 /* Stream operations. */
1040 else if (p
[0] == 'D')
1042 /* Controlled type operation. */
1065 /* Standard separator. Handled first. */
1070 /* Overloading number. */
1073 while (ISDIGIT (*p
) || (p
[0] == '_' && ISDIGIT (p
[1])));
1077 while (p
[0] == 'n' || p
[0] == 'b')
1081 else if (p
[0] == '_' && p
[1] != '_')
1083 /* Special names. */
1084 static const char * const special
[][2] = {
1085 { "_elabb", "'Elab_Body" },
1086 { "_elabs", "'Elab_Spec" },
1087 { "_size", "'Size" },
1088 { "_alignment", "'Alignment" },
1089 { "_assign", ".\":=\"" },
1094 for (k
= 0; special
[k
][0] != NULL
; k
++)
1096 size_t slen
= strlen (special
[k
][0]);
1097 if (strncmp (p
, special
[k
][0], slen
) == 0)
1100 slen
= strlen (special
[k
][1]);
1101 memcpy (d
, special
[k
][1], slen
);
1106 if (special
[k
][0] != NULL
)
1117 else if (p
[1] == 'B' || p
[1] == 'E')
1119 /* Entry Body or barrier Evaluation. */
1121 while (ISDIGIT (*p
))
1123 if (p
[0] == 's' && p
[1] == 0)
1132 if (p
[0] == '.' && ISDIGIT (p
[1]))
1134 /* Nested subprogram. */
1136 while (ISDIGIT (*p
))
1141 /* End of mangled name. */
1151 len0
= strlen (mangled
);
1152 demangled
= XNEWVEC (char, len0
+ 3);
1154 if (mangled
[0] == '<')
1155 strcpy (demangled
, mangled
);
1157 sprintf (demangled
, "<%s>", mangled
);
1162 /* This function performs most of what cplus_demangle use to do, but
1163 to be able to demangle a name with a B, K or n code, we need to
1164 have a longer term memory of what types have been seen. The original
1165 now initializes and cleans up the squangle code info, while internal
1166 calls go directly to this routine to avoid resetting that info. */
1169 internal_cplus_demangle (struct work_stuff
*work
, const char *mangled
)
1174 char *demangled
= NULL
;
1176 s1
= work
->constructor
;
1177 s2
= work
->destructor
;
1178 s3
= work
->static_type
;
1179 s4
= work
->type_quals
;
1180 work
->constructor
= work
->destructor
= 0;
1181 work
->type_quals
= TYPE_UNQUALIFIED
;
1182 work
->dllimported
= 0;
1184 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
1186 string_init (&decl
);
1188 /* First check to see if gnu style demangling is active and if the
1189 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1190 recognize one of the gnu special forms rather than looking for a
1191 standard prefix. In particular, don't worry about whether there
1192 is a "__" string in the mangled string. Consider "_$_5__foo" for
1195 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
1197 success
= gnu_special (work
, &mangled
, &decl
);
1200 delete_work_stuff (work
);
1201 string_delete (&decl
);
1206 success
= demangle_prefix (work
, &mangled
, &decl
);
1208 if (success
&& (*mangled
!= '\0'))
1210 success
= demangle_signature (work
, &mangled
, &decl
);
1212 if (work
->constructor
== 2)
1214 string_prepend (&decl
, "global constructors keyed to ");
1215 work
->constructor
= 0;
1217 else if (work
->destructor
== 2)
1219 string_prepend (&decl
, "global destructors keyed to ");
1220 work
->destructor
= 0;
1222 else if (work
->dllimported
== 1)
1224 string_prepend (&decl
, "import stub for ");
1225 work
->dllimported
= 0;
1227 demangled
= mop_up (work
, &decl
, success
);
1229 work
->constructor
= s1
;
1230 work
->destructor
= s2
;
1231 work
->static_type
= s3
;
1232 work
->type_quals
= s4
;
1237 /* Clear out and squangling related storage */
1239 squangle_mop_up (struct work_stuff
*work
)
1241 /* clean up the B and K type mangling types. */
1242 forget_B_and_K_types (work
);
1243 if (work
-> btypevec
!= NULL
)
1245 free ((char *) work
-> btypevec
);
1246 work
->btypevec
= NULL
;
1249 if (work
-> ktypevec
!= NULL
)
1251 free ((char *) work
-> ktypevec
);
1252 work
->ktypevec
= NULL
;
1258 /* Copy the work state and storage. */
1261 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1265 delete_work_stuff (to
);
1267 /* Shallow-copy scalars. */
1268 memcpy (to
, from
, sizeof (*to
));
1270 /* Deep-copy dynamic storage. */
1271 if (from
->typevec_size
)
1272 to
->typevec
= XNEWVEC (char *, from
->typevec_size
);
1274 for (i
= 0; i
< from
->ntypes
; i
++)
1276 int len
= strlen (from
->typevec
[i
]) + 1;
1278 to
->typevec
[i
] = XNEWVEC (char, len
);
1279 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1283 to
->ktypevec
= XNEWVEC (char *, from
->ksize
);
1285 for (i
= 0; i
< from
->numk
; i
++)
1287 int len
= strlen (from
->ktypevec
[i
]) + 1;
1289 to
->ktypevec
[i
] = XNEWVEC (char, len
);
1290 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1294 to
->btypevec
= XNEWVEC (char *, from
->bsize
);
1296 for (i
= 0; i
< from
->numb
; i
++)
1298 int len
= strlen (from
->btypevec
[i
]) + 1;
1300 to
->btypevec
[i
] = XNEWVEC (char , len
);
1301 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1304 if (from
->ntmpl_args
)
1305 to
->tmpl_argvec
= XNEWVEC (char *, from
->ntmpl_args
);
1307 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1309 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1311 to
->tmpl_argvec
[i
] = XNEWVEC (char, len
);
1312 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1315 if (from
->previous_argument
)
1317 to
->previous_argument
= XNEW (string
);
1318 string_init (to
->previous_argument
);
1319 string_appends (to
->previous_argument
, from
->previous_argument
);
1324 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1327 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1329 /* Discard the remembered types, if any. */
1331 forget_types (work
);
1332 if (work
-> typevec
!= NULL
)
1334 free ((char *) work
-> typevec
);
1335 work
-> typevec
= NULL
;
1336 work
-> typevec_size
= 0;
1338 if (work
->tmpl_argvec
)
1342 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1343 free ((char*) work
->tmpl_argvec
[i
]);
1345 free ((char*) work
->tmpl_argvec
);
1346 work
->tmpl_argvec
= NULL
;
1348 if (work
->previous_argument
)
1350 string_delete (work
->previous_argument
);
1351 free ((char*) work
->previous_argument
);
1352 work
->previous_argument
= NULL
;
1357 /* Delete all dynamic storage in work_stuff. */
1359 delete_work_stuff (struct work_stuff
*work
)
1361 delete_non_B_K_work_stuff (work
);
1362 squangle_mop_up (work
);
1366 /* Clear out any mangled storage */
1369 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1371 char *demangled
= NULL
;
1373 delete_non_B_K_work_stuff (work
);
1375 /* If demangling was successful, ensure that the demangled string is null
1376 terminated and return it. Otherwise, free the demangling decl. */
1380 string_delete (declp
);
1384 string_appendn (declp
, "", 1);
1385 demangled
= declp
->b
;
1394 demangle_signature -- demangle the signature part of a mangled name
1399 demangle_signature (struct work_stuff *work, const char **mangled,
1404 Consume and demangle the signature portion of the mangled name.
1406 DECLP is the string where demangled output is being built. At
1407 entry it contains the demangled root name from the mangled name
1408 prefix. I.E. either a demangled operator name or the root function
1409 name. In some special cases, it may contain nothing.
1411 *MANGLED points to the current unconsumed location in the mangled
1412 name. As tokens are consumed and demangling is performed, the
1413 pointer is updated to continuously point at the next token to
1416 Demangling GNU style mangled names is nasty because there is no
1417 explicit token that marks the start of the outermost function
1421 demangle_signature (struct work_stuff
*work
,
1422 const char **mangled
, string
*declp
)
1426 int expect_func
= 0;
1427 int expect_return_type
= 0;
1428 const char *oldmangled
= NULL
;
1432 while (success
&& (**mangled
!= '\0'))
1437 oldmangled
= *mangled
;
1438 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1440 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1441 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1447 oldmangled
= *mangled
;
1448 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1449 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1457 /* Static member function */
1458 if (oldmangled
== NULL
)
1460 oldmangled
= *mangled
;
1463 work
-> static_type
= 1;
1469 work
->type_quals
|= code_for_qualifier (**mangled
);
1471 /* a qualified member function */
1472 if (oldmangled
== NULL
)
1473 oldmangled
= *mangled
;
1478 /* Local class name follows after "Lnnn_" */
1481 while (**mangled
&& (**mangled
!= '_'))
1492 case '0': case '1': case '2': case '3': case '4':
1493 case '5': case '6': case '7': case '8': case '9':
1494 if (oldmangled
== NULL
)
1496 oldmangled
= *mangled
;
1498 work
->temp_start
= -1; /* uppermost call to demangle_class */
1499 success
= demangle_class (work
, mangled
, declp
);
1502 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1504 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1506 /* EDG and others will have the "F", so we let the loop cycle
1507 if we are looking at one. */
1508 if (**mangled
!= 'F')
1517 success
= do_type (work
, mangled
, &s
);
1520 string_append (&s
, SCOPE_STRING (work
));
1521 string_prepends (declp
, &s
);
1531 /* ARM/HP style demangling includes a specific 'F' character after
1532 the class name. For GNU style, it is just implied. So we can
1533 safely just consume any 'F' at this point and be compatible
1534 with either style. */
1540 /* For lucid/ARM/HP style we have to forget any types we might
1541 have remembered up to this point, since they were not argument
1542 types. GNU style considers all types seen as available for
1543 back references. See comment in demangle_args() */
1545 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1547 forget_types (work
);
1549 success
= demangle_args (work
, mangled
, declp
);
1550 /* After picking off the function args, we expect to either
1551 find the function return type (preceded by an '_') or the
1552 end of the string. */
1553 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1556 /* At this level, we do not care about the return type. */
1557 success
= do_type (work
, mangled
, &tname
);
1558 string_delete (&tname
);
1565 string_init(&trawname
);
1566 string_init(&tname
);
1567 if (oldmangled
== NULL
)
1569 oldmangled
= *mangled
;
1571 success
= demangle_template (work
, mangled
, &tname
,
1575 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1577 string_append (&tname
, SCOPE_STRING (work
));
1579 string_prepends(declp
, &tname
);
1580 if (work
-> destructor
& 1)
1582 string_prepend (&trawname
, "~");
1583 string_appends (declp
, &trawname
);
1584 work
->destructor
-= 1;
1586 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1588 string_appends (declp
, &trawname
);
1589 work
->constructor
-= 1;
1591 string_delete(&trawname
);
1592 string_delete(&tname
);
1598 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1600 /* Read the return type. */
1604 success
= do_type (work
, mangled
, &return_type
);
1605 APPEND_BLANK (&return_type
);
1607 string_prepends (declp
, &return_type
);
1608 string_delete (&return_type
);
1612 /* At the outermost level, we cannot have a return type specified,
1613 so if we run into another '_' at this point we are dealing with
1614 a mangled name that is either bogus, or has been mangled by
1615 some algorithm we don't know how to deal with. So just
1616 reject the entire demangling. */
1617 /* However, "_nnn" is an expected suffix for alternate entry point
1618 numbered nnn for a function, with HP aCC, so skip over that
1619 without reporting failure. pai/1997-09-04 */
1623 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1631 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1633 /* A G++ template function. Read the template arguments. */
1634 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1636 if (!(work
->constructor
& 1))
1637 expect_return_type
= 1;
1646 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1648 /* Assume we have stumbled onto the first outermost function
1649 argument token, and start processing args. */
1651 success
= demangle_args (work
, mangled
, declp
);
1655 /* Non-GNU demanglers use a specific token to mark the start
1656 of the outermost function argument tokens. Typically 'F',
1657 for ARM/HP-demangling, for example. So if we find something
1658 we are not prepared for, it must be an error. */
1664 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1667 if (success
&& expect_func
)
1670 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1672 forget_types (work
);
1674 success
= demangle_args (work
, mangled
, declp
);
1675 /* Since template include the mangling of their return types,
1676 we must set expect_func to 0 so that we don't try do
1677 demangle more arguments the next time we get here. */
1682 if (success
&& !func_done
)
1684 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1686 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1687 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1688 first case, and need to ensure that the '(void)' gets added to
1689 the current declp. Note that with ARM/HP, the first case
1690 represents the name of a static data member 'foo::bar',
1691 which is in the current declp, so we leave it alone. */
1692 success
= demangle_args (work
, mangled
, declp
);
1695 if (success
&& PRINT_ARG_TYPES
)
1697 if (work
->static_type
)
1698 string_append (declp
, " static");
1699 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1701 APPEND_BLANK (declp
);
1702 string_append (declp
, qualifier_string (work
->type_quals
));
1712 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1717 if (work
-> static_type
)
1719 string_append (declp
, *mangled
+ 1);
1720 *mangled
+= strlen (*mangled
);
1725 success
= demangle_args (work
, mangled
, declp
);
1733 demangle_template_template_parm (struct work_stuff
*work
,
1734 const char **mangled
, string
*tname
)
1742 string_append (tname
, "template <");
1743 /* get size of template parameter list */
1744 if (get_count (mangled
, &r
))
1746 for (i
= 0; i
< r
; i
++)
1750 string_append (tname
, ", ");
1753 /* Z for type parameters */
1754 if (**mangled
== 'Z')
1757 string_append (tname
, "class");
1759 /* z for template parameters */
1760 else if (**mangled
== 'z')
1764 demangle_template_template_parm (work
, mangled
, tname
);
1772 /* temp is initialized in do_type */
1773 success
= do_type (work
, mangled
, &temp
);
1776 string_appends (tname
, &temp
);
1778 string_delete(&temp
);
1788 if (tname
->p
[-1] == '>')
1789 string_append (tname
, " ");
1790 string_append (tname
, "> class");
1795 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1796 string
*s
, type_kind_t tk
)
1798 int need_operator
= 0;
1802 string_appendn (s
, "(", 1);
1804 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1813 len
= strlen (*mangled
);
1815 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1817 size_t l
= strlen (optable
[i
].in
);
1820 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1822 string_appendn (s
, " ", 1);
1823 string_append (s
, optable
[i
].out
);
1824 string_appendn (s
, " ", 1);
1837 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1840 if (**mangled
!= 'W')
1844 string_appendn (s
, ")", 1);
1852 demangle_integral_value (struct work_stuff
*work
,
1853 const char **mangled
, string
*s
)
1857 if (**mangled
== 'E')
1858 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1859 else if (**mangled
== 'Q' || **mangled
== 'K')
1860 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1865 /* By default, we let the number decide whether we shall consume an
1867 int multidigit_without_leading_underscore
= 0;
1868 int leave_following_underscore
= 0;
1872 if (**mangled
== '_')
1874 if (mangled
[0][1] == 'm')
1876 /* Since consume_count_with_underscores does not handle the
1877 `m'-prefix we must do it here, using consume_count and
1878 adjusting underscores: we have to consume the underscore
1879 matching the prepended one. */
1880 multidigit_without_leading_underscore
= 1;
1881 string_appendn (s
, "-", 1);
1886 /* Do not consume a following underscore;
1887 consume_count_with_underscores will consume what
1888 should be consumed. */
1889 leave_following_underscore
= 1;
1894 /* Negative numbers are indicated with a leading `m'. */
1895 if (**mangled
== 'm')
1897 string_appendn (s
, "-", 1);
1900 /* Since consume_count_with_underscores does not handle
1901 multi-digit numbers that do not start with an underscore,
1902 and this number can be an integer template parameter,
1903 we have to call consume_count. */
1904 multidigit_without_leading_underscore
= 1;
1905 /* These multi-digit numbers never end on an underscore,
1906 so if there is one then don't eat it. */
1907 leave_following_underscore
= 1;
1910 /* We must call consume_count if we expect to remove a trailing
1911 underscore, since consume_count_with_underscores expects
1912 the leading underscore (that we consumed) if it is to handle
1913 multi-digit numbers. */
1914 if (multidigit_without_leading_underscore
)
1915 value
= consume_count (mangled
);
1917 value
= consume_count_with_underscores (mangled
);
1921 char buf
[INTBUF_SIZE
];
1922 sprintf (buf
, "%d", value
);
1923 string_append (s
, buf
);
1925 /* Numbers not otherwise delimited, might have an underscore
1926 appended as a delimeter, which we should skip.
1928 ??? This used to always remove a following underscore, which
1929 is wrong. If other (arbitrary) cases are followed by an
1930 underscore, we need to do something more radical. */
1932 if ((value
> 9 || multidigit_without_leading_underscore
)
1933 && ! leave_following_underscore
1934 && **mangled
== '_')
1945 /* Demangle the real value in MANGLED. */
1948 demangle_real_value (struct work_stuff
*work
,
1949 const char **mangled
, string
*s
)
1951 if (**mangled
== 'E')
1952 return demangle_expression (work
, mangled
, s
, tk_real
);
1954 if (**mangled
== 'm')
1956 string_appendn (s
, "-", 1);
1959 while (ISDIGIT ((unsigned char)**mangled
))
1961 string_appendn (s
, *mangled
, 1);
1964 if (**mangled
== '.') /* fraction */
1966 string_appendn (s
, ".", 1);
1968 while (ISDIGIT ((unsigned char)**mangled
))
1970 string_appendn (s
, *mangled
, 1);
1974 if (**mangled
== 'e') /* exponent */
1976 string_appendn (s
, "e", 1);
1978 while (ISDIGIT ((unsigned char)**mangled
))
1980 string_appendn (s
, *mangled
, 1);
1989 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
1990 string
*s
, type_kind_t tk
)
1994 if (**mangled
== 'Y')
1996 /* The next argument is a template parameter. */
2000 idx
= consume_count_with_underscores (mangled
);
2002 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2003 || consume_count_with_underscores (mangled
) == -1)
2005 if (work
->tmpl_argvec
)
2006 string_append (s
, work
->tmpl_argvec
[idx
]);
2008 string_append_template_idx (s
, idx
);
2010 else if (tk
== tk_integral
)
2011 success
= demangle_integral_value (work
, mangled
, s
);
2012 else if (tk
== tk_char
)
2016 if (**mangled
== 'm')
2018 string_appendn (s
, "-", 1);
2021 string_appendn (s
, "'", 1);
2022 val
= consume_count(mangled
);
2029 string_appendn (s
, &tmp
[0], 1);
2030 string_appendn (s
, "'", 1);
2033 else if (tk
== tk_bool
)
2035 int val
= consume_count (mangled
);
2037 string_appendn (s
, "false", 5);
2039 string_appendn (s
, "true", 4);
2043 else if (tk
== tk_real
)
2044 success
= demangle_real_value (work
, mangled
, s
);
2045 else if (tk
== tk_pointer
|| tk
== tk_reference
)
2047 if (**mangled
== 'Q')
2048 success
= demangle_qualified (work
, mangled
, s
,
2053 int symbol_len
= consume_count (mangled
);
2054 if (symbol_len
== -1)
2056 if (symbol_len
== 0)
2057 string_appendn (s
, "0", 1);
2060 char *p
= XNEWVEC (char, symbol_len
+ 1), *q
;
2061 strncpy (p
, *mangled
, symbol_len
);
2062 p
[symbol_len
] = '\0';
2063 /* We use cplus_demangle here, rather than
2064 internal_cplus_demangle, because the name of the entity
2065 mangled here does not make use of any of the squangling
2066 or type-code information we have built up thus far; it is
2067 mangled independently. */
2068 q
= cplus_demangle (p
, work
->options
);
2069 if (tk
== tk_pointer
)
2070 string_appendn (s
, "&", 1);
2071 /* FIXME: Pointer-to-member constants should get a
2072 qualifying class name here. */
2075 string_append (s
, q
);
2079 string_append (s
, p
);
2082 *mangled
+= symbol_len
;
2089 /* Demangle the template name in MANGLED. The full name of the
2090 template (e.g., S<int>) is placed in TNAME. The name without the
2091 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2092 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2093 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2094 the template is remembered in the list of back-referenceable
2098 demangle_template (struct work_stuff
*work
, const char **mangled
,
2099 string
*tname
, string
*trawname
,
2100 int is_type
, int remember
)
2106 int is_java_array
= 0;
2112 /* get template name */
2113 if (**mangled
== 'z')
2119 idx
= consume_count_with_underscores (mangled
);
2121 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2122 || consume_count_with_underscores (mangled
) == -1)
2125 if (work
->tmpl_argvec
)
2127 string_append (tname
, work
->tmpl_argvec
[idx
]);
2129 string_append (trawname
, work
->tmpl_argvec
[idx
]);
2133 string_append_template_idx (tname
, idx
);
2135 string_append_template_idx (trawname
, idx
);
2140 if ((r
= consume_count (mangled
)) <= 0
2141 || (int) strlen (*mangled
) < r
)
2145 is_java_array
= (work
-> options
& DMGL_JAVA
)
2146 && strncmp (*mangled
, "JArray1Z", 8) == 0;
2147 if (! is_java_array
)
2149 string_appendn (tname
, *mangled
, r
);
2152 string_appendn (trawname
, *mangled
, r
);
2157 string_append (tname
, "<");
2158 /* get size of template parameter list */
2159 if (!get_count (mangled
, &r
))
2165 /* Create an array for saving the template argument values. */
2166 work
->tmpl_argvec
= XNEWVEC (char *, r
);
2167 work
->ntmpl_args
= r
;
2168 for (i
= 0; i
< r
; i
++)
2169 work
->tmpl_argvec
[i
] = 0;
2171 for (i
= 0; i
< r
; i
++)
2175 string_append (tname
, ", ");
2177 /* Z for type parameters */
2178 if (**mangled
== 'Z')
2181 /* temp is initialized in do_type */
2182 success
= do_type (work
, mangled
, &temp
);
2185 string_appends (tname
, &temp
);
2189 /* Save the template argument. */
2190 int len
= temp
.p
- temp
.b
;
2191 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2192 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2193 work
->tmpl_argvec
[i
][len
] = '\0';
2196 string_delete(&temp
);
2202 /* z for template parameters */
2203 else if (**mangled
== 'z')
2207 success
= demangle_template_template_parm (work
, mangled
, tname
);
2210 && (r2
= consume_count (mangled
)) > 0
2211 && (int) strlen (*mangled
) >= r2
)
2213 string_append (tname
, " ");
2214 string_appendn (tname
, *mangled
, r2
);
2217 /* Save the template argument. */
2219 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2220 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2221 work
->tmpl_argvec
[i
][len
] = '\0';
2235 /* otherwise, value parameter */
2237 /* temp is initialized in do_type */
2238 success
= do_type (work
, mangled
, &temp
);
2239 string_delete(&temp
);
2251 success
= demangle_template_value_parm (work
, mangled
, s
,
2252 (type_kind_t
) success
);
2264 int len
= s
->p
- s
->b
;
2265 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2266 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2267 work
->tmpl_argvec
[i
][len
] = '\0';
2269 string_appends (tname
, s
);
2277 string_append (tname
, "[]");
2281 if (tname
->p
[-1] == '>')
2282 string_append (tname
, " ");
2283 string_append (tname
, ">");
2286 if (is_type
&& remember
)
2288 const int bindex
= register_Btype (work
);
2289 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2293 if (work -> static_type)
2295 string_append (declp, *mangled + 1);
2296 *mangled += strlen (*mangled);
2301 success = demangle_args (work, mangled, declp);
2309 arm_pt (struct work_stuff
*work
, const char *mangled
,
2310 int n
, const char **anchor
, const char **args
)
2312 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2313 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2314 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2317 *args
= *anchor
+ 6;
2318 len
= consume_count (args
);
2321 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2327 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2329 if ((*anchor
= strstr (mangled
, "__tm__"))
2330 || (*anchor
= strstr (mangled
, "__ps__"))
2331 || (*anchor
= strstr (mangled
, "__pt__")))
2334 *args
= *anchor
+ 6;
2335 len
= consume_count (args
);
2338 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2344 else if ((*anchor
= strstr (mangled
, "__S")))
2347 *args
= *anchor
+ 3;
2348 len
= consume_count (args
);
2351 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2363 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2364 int n
, string
*declp
)
2368 const char *e
= *mangled
+ n
;
2371 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2373 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2375 char *start_spec_args
= NULL
;
2378 /* First check for and omit template specialization pseudo-arguments,
2379 such as in "Spec<#1,#1.*>" */
2380 start_spec_args
= strchr (*mangled
, '<');
2381 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2382 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2384 string_appendn (declp
, *mangled
, n
);
2385 (*mangled
) += n
+ 1;
2387 if (work
->temp_start
== -1) /* non-recursive call */
2388 work
->temp_start
= declp
->p
- declp
->b
;
2390 /* We want to unconditionally demangle parameter types in
2391 template parameters. */
2392 hold_options
= work
->options
;
2393 work
->options
|= DMGL_PARAMS
;
2395 string_append (declp
, "<");
2398 string_delete (&arg
);
2402 /* 'T' signals a type parameter */
2404 if (!do_type (work
, mangled
, &arg
))
2405 goto hpacc_template_args_done
;
2410 /* 'U' or 'S' signals an integral value */
2411 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2412 goto hpacc_template_args_done
;
2416 /* 'A' signals a named constant expression (literal) */
2417 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2418 goto hpacc_template_args_done
;
2422 /* Today, 1997-09-03, we have only the above types
2423 of template parameters */
2424 /* FIXME: maybe this should fail and return null */
2425 goto hpacc_template_args_done
;
2427 string_appends (declp
, &arg
);
2428 /* Check if we're at the end of template args.
2429 0 if at end of static member of template class,
2430 _ if done with template args for a function */
2431 if ((**mangled
== '\000') || (**mangled
== '_'))
2434 string_append (declp
, ",");
2436 hpacc_template_args_done
:
2437 string_append (declp
, ">");
2438 string_delete (&arg
);
2439 if (**mangled
== '_')
2441 work
->options
= hold_options
;
2444 /* ARM template? (Also handles HP cfront extensions) */
2445 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2451 string_appendn (declp
, *mangled
, p
- *mangled
);
2452 if (work
->temp_start
== -1) /* non-recursive call */
2453 work
->temp_start
= declp
->p
- declp
->b
;
2455 /* We want to unconditionally demangle parameter types in
2456 template parameters. */
2457 hold_options
= work
->options
;
2458 work
->options
|= DMGL_PARAMS
;
2460 string_append (declp
, "<");
2461 /* should do error checking here */
2463 string_delete (&arg
);
2465 /* Check for type or literal here */
2468 /* HP cfront extensions to ARM for template args */
2469 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2470 /* FIXME: We handle only numeric literals for HP cfront */
2472 /* A typed constant value follows */
2474 if (!do_type (work
, &args
, &type_str
))
2475 goto cfront_template_args_done
;
2476 string_append (&arg
, "(");
2477 string_appends (&arg
, &type_str
);
2478 string_delete (&type_str
);
2479 string_append (&arg
, ")");
2481 goto cfront_template_args_done
;
2483 /* Now snarf a literal value following 'L' */
2484 if (!snarf_numeric_literal (&args
, &arg
))
2485 goto cfront_template_args_done
;
2489 /* Snarf a literal following 'L' */
2491 if (!snarf_numeric_literal (&args
, &arg
))
2492 goto cfront_template_args_done
;
2495 /* Not handling other HP cfront stuff */
2497 const char* old_args
= args
;
2498 if (!do_type (work
, &args
, &arg
))
2499 goto cfront_template_args_done
;
2501 /* Fail if we didn't make any progress: prevent infinite loop. */
2502 if (args
== old_args
)
2504 work
->options
= hold_options
;
2509 string_appends (declp
, &arg
);
2510 string_append (declp
, ",");
2512 cfront_template_args_done
:
2513 string_delete (&arg
);
2515 --declp
->p
; /* remove extra comma */
2516 string_append (declp
, ">");
2517 work
->options
= hold_options
;
2519 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2520 && (*mangled
)[9] == 'N'
2521 && (*mangled
)[8] == (*mangled
)[10]
2522 && strchr (cplus_markers
, (*mangled
)[8]))
2524 /* A member of the anonymous namespace. */
2525 string_append (declp
, "{anonymous}");
2529 if (work
->temp_start
== -1) /* non-recursive call only */
2530 work
->temp_start
= 0; /* disable in recursive calls */
2531 string_appendn (declp
, *mangled
, n
);
2536 /* Extract a class name, possibly a template with arguments, from the
2537 mangled string; qualifiers, local class indicators, etc. have
2538 already been dealt with */
2541 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2547 n
= consume_count (mangled
);
2550 if ((int) strlen (*mangled
) >= n
)
2552 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2563 demangle_class -- demangle a mangled class sequence
2568 demangle_class (struct work_stuff *work, const char **mangled,
2573 DECLP points to the buffer into which demangling is being done.
2575 *MANGLED points to the current token to be demangled. On input,
2576 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2577 On exit, it points to the next token after the mangled class on
2578 success, or the first unconsumed token on failure.
2580 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2581 we are demangling a constructor or destructor. In this case
2582 we prepend "class::class" or "class::~class" to DECLP.
2584 Otherwise, we prepend "class::" to the current DECLP.
2586 Reset the constructor/destructor flags once they have been
2587 "consumed". This allows demangle_class to be called later during
2588 the same demangling, to do normal class demangling.
2590 Returns 1 if demangling is successful, 0 otherwise.
2595 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2600 char *save_class_name_end
= 0;
2602 string_init (&class_name
);
2603 btype
= register_Btype (work
);
2604 if (demangle_class_name (work
, mangled
, &class_name
))
2606 save_class_name_end
= class_name
.p
;
2607 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2609 /* adjust so we don't include template args */
2610 if (work
->temp_start
&& (work
->temp_start
!= -1))
2612 class_name
.p
= class_name
.b
+ work
->temp_start
;
2614 string_prepends (declp
, &class_name
);
2615 if (work
-> destructor
& 1)
2617 string_prepend (declp
, "~");
2618 work
-> destructor
-= 1;
2622 work
-> constructor
-= 1;
2625 class_name
.p
= save_class_name_end
;
2626 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2627 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2628 string_prepend (declp
, SCOPE_STRING (work
));
2629 string_prepends (declp
, &class_name
);
2632 string_delete (&class_name
);
2637 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2638 the rightmost guess.
2640 Find the correct "__"-sequence where the function name ends and the
2641 signature starts, which is ambiguous with GNU mangling.
2642 Call demangle_signature here, so we can make sure we found the right
2643 one; *mangled will be consumed so caller will not make further calls to
2644 demangle_signature. */
2647 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2648 string
*declp
, const char *scan
)
2650 const char *mangle_init
= *mangled
;
2653 struct work_stuff work_init
;
2655 if (*(scan
+ 2) == '\0')
2658 /* Do not iterate for some demangling modes, or if there's only one
2659 "__"-sequence. This is the normal case. */
2660 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2661 || strstr (scan
+ 2, "__") == NULL
)
2662 return demangle_function_name (work
, mangled
, declp
, scan
);
2664 /* Save state so we can restart if the guess at the correct "__" was
2666 string_init (&decl_init
);
2667 string_appends (&decl_init
, declp
);
2668 memset (&work_init
, 0, sizeof work_init
);
2669 work_stuff_copy_to_from (&work_init
, work
);
2671 /* Iterate over occurrences of __, allowing names and types to have a
2672 "__" sequence in them. We must start with the first (not the last)
2673 occurrence, since "__" most often occur between independent mangled
2674 parts, hence starting at the last occurence inside a signature
2675 might get us a "successful" demangling of the signature. */
2679 if (demangle_function_name (work
, mangled
, declp
, scan
))
2681 success
= demangle_signature (work
, mangled
, declp
);
2686 /* Reset demangle state for the next round. */
2687 *mangled
= mangle_init
;
2688 string_clear (declp
);
2689 string_appends (declp
, &decl_init
);
2690 work_stuff_copy_to_from (work
, &work_init
);
2692 /* Leave this underscore-sequence. */
2695 /* Scan for the next "__" sequence. */
2696 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2699 /* Move to last "__" in this sequence. */
2700 while (*scan
&& *scan
== '_')
2705 /* Delete saved state. */
2706 delete_work_stuff (&work_init
);
2707 string_delete (&decl_init
);
2716 demangle_prefix -- consume the mangled name prefix and find signature
2721 demangle_prefix (struct work_stuff *work, const char **mangled,
2726 Consume and demangle the prefix of the mangled name.
2727 While processing the function name root, arrange to call
2728 demangle_signature if the root is ambiguous.
2730 DECLP points to the string buffer into which demangled output is
2731 placed. On entry, the buffer is empty. On exit it contains
2732 the root function name, the demangled operator name, or in some
2733 special cases either nothing or the completely demangled result.
2735 MANGLED points to the current pointer into the mangled name. As each
2736 token of the mangled name is consumed, it is updated. Upon entry
2737 the current mangled name pointer points to the first character of
2738 the mangled name. Upon exit, it should point to the first character
2739 of the signature if demangling was successful, or to the first
2740 unconsumed character if demangling of the prefix was unsuccessful.
2742 Returns 1 on success, 0 otherwise.
2746 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2753 if (strlen(*mangled
) > 6
2754 && (strncmp(*mangled
, "_imp__", 6) == 0
2755 || strncmp(*mangled
, "__imp_", 6) == 0))
2757 /* it's a symbol imported from a PE dynamic library. Check for both
2758 new style prefix _imp__ and legacy __imp_ used by older versions
2761 work
->dllimported
= 1;
2763 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2765 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2766 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2768 if ((*mangled
)[9] == 'D')
2770 /* it's a GNU global destructor to be executed at program exit */
2772 work
->destructor
= 2;
2773 if (gnu_special (work
, mangled
, declp
))
2776 else if ((*mangled
)[9] == 'I')
2778 /* it's a GNU global constructor to be executed at program init */
2780 work
->constructor
= 2;
2781 if (gnu_special (work
, mangled
, declp
))
2786 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2788 /* it's a ARM global destructor to be executed at program exit */
2790 work
->destructor
= 2;
2792 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2794 /* it's a ARM global constructor to be executed at program initial */
2796 work
->constructor
= 2;
2799 /* This block of code is a reduction in strength time optimization
2801 scan = strstr (*mangled, "__"); */
2807 scan
= strchr (scan
, '_');
2808 } while (scan
!= NULL
&& *++scan
!= '_');
2810 if (scan
!= NULL
) --scan
;
2815 /* We found a sequence of two or more '_', ensure that we start at
2816 the last pair in the sequence. */
2817 i
= strspn (scan
, "_");
2828 else if (work
-> static_type
)
2830 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2835 else if ((scan
== *mangled
)
2836 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2837 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2839 /* The ARM says nothing about the mangling of local variables.
2840 But cfront mangles local variables by prepending __<nesting_level>
2841 to them. As an extension to ARM demangling we handle this case. */
2842 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2843 && ISDIGIT ((unsigned char)scan
[2]))
2845 *mangled
= scan
+ 2;
2846 consume_count (mangled
);
2847 string_append (declp
, *mangled
);
2848 *mangled
+= strlen (*mangled
);
2853 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2854 names like __Q2_3foo3bar for nested type names. So don't accept
2855 this style of constructor for cfront demangling. A GNU
2856 style member-template constructor starts with 'H'. */
2857 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2858 work
-> constructor
+= 1;
2859 *mangled
= scan
+ 2;
2862 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2864 /* Cfront-style parameterized type. Handled later as a signature. */
2868 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2870 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2871 || (scan
[2] == 'p' && scan
[3] == 's')
2872 || (scan
[2] == 'p' && scan
[3] == 't')))
2874 /* EDG-style parameterized type. Handled later as a signature. */
2878 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2880 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2881 && (scan
[2] != 't'))
2883 /* Mangled name starts with "__". Skip over any leading '_' characters,
2884 then find the next "__" that separates the prefix from the signature.
2886 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2887 || (arm_special (mangled
, declp
) == 0))
2889 while (*scan
== '_')
2893 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2895 /* No separator (I.E. "__not_mangled"), or empty signature
2896 (I.E. "__not_mangled_either__") */
2900 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2903 else if (*(scan
+ 2) != '\0')
2905 /* Mangled name does not start with "__" but does have one somewhere
2906 in there with non empty stuff after it. Looks like a global
2907 function name. Iterate over all "__":s until the right
2909 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2913 /* Doesn't look like a mangled name */
2917 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2919 string_append (declp
, *mangled
);
2920 *mangled
+= strlen (*mangled
);
2930 gnu_special -- special handling of gnu mangled strings
2935 gnu_special (struct work_stuff *work, const char **mangled,
2941 Process some special GNU style mangling forms that don't fit
2942 the normal pattern. For example:
2944 _$_3foo (destructor for class foo)
2945 _vt$foo (foo virtual table)
2946 _vt$foo$bar (foo::bar virtual table)
2947 __vt_foo (foo virtual table, new style with thunks)
2948 _3foo$varname (static data member)
2949 _Q22rs2tu$vw (static data member)
2950 __t6vector1Zii (constructor with template)
2951 __thunk_4__$_7ostream (virtual function thunk)
2955 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2961 if ((*mangled
)[0] == '_'
2962 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2963 && (*mangled
)[2] == '_')
2965 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2967 work
-> destructor
+= 1;
2969 else if ((*mangled
)[0] == '_'
2970 && (((*mangled
)[1] == '_'
2971 && (*mangled
)[2] == 'v'
2972 && (*mangled
)[3] == 't'
2973 && (*mangled
)[4] == '_')
2974 || ((*mangled
)[1] == 'v'
2975 && (*mangled
)[2] == 't'
2976 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2978 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2979 and create the decl. Note that we consume the entire mangled
2980 input string, which means that demangle_signature has no work
2982 if ((*mangled
)[2] == 'v')
2983 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2985 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2986 while (**mangled
!= '\0')
2992 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2995 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2999 if (ISDIGIT((unsigned char)*mangled
[0]))
3001 n
= consume_count(mangled
);
3002 /* We may be seeing a too-large size, or else a
3003 ".<digits>" indicating a static local symbol. In
3004 any case, declare victory and move on; *don't* try
3005 to use n to allocate. */
3006 if (n
> (int) strlen (*mangled
))
3019 n
= strcspn (*mangled
, cplus_markers
);
3021 string_appendn (declp
, *mangled
, n
);
3025 p
= strpbrk (*mangled
, cplus_markers
);
3026 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
3030 string_append (declp
, SCOPE_STRING (work
));
3041 string_append (declp
, " virtual table");
3043 else if ((*mangled
)[0] == '_'
3044 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
3045 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
3047 /* static data member, "_3foo$varname" for example */
3053 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3056 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3059 n
= consume_count (mangled
);
3060 if (n
< 0 || n
> (long) strlen (*mangled
))
3066 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
3067 && (*mangled
)[9] == 'N'
3068 && (*mangled
)[8] == (*mangled
)[10]
3069 && strchr (cplus_markers
, (*mangled
)[8]))
3071 /* A member of the anonymous namespace. There's information
3072 about what identifier or filename it was keyed to, but
3073 it's just there to make the mangled name unique; we just
3075 string_append (declp
, "{anonymous}");
3078 /* Now p points to the marker before the N, so we need to
3079 update it to the first marker after what we consumed. */
3080 p
= strpbrk (*mangled
, cplus_markers
);
3084 string_appendn (declp
, *mangled
, n
);
3087 if (success
&& (p
== *mangled
))
3089 /* Consumed everything up to the cplus_marker, append the
3092 string_append (declp
, SCOPE_STRING (work
));
3093 n
= strlen (*mangled
);
3094 string_appendn (declp
, *mangled
, n
);
3102 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
3107 delta
= consume_count (mangled
);
3112 char *method
= internal_cplus_demangle (work
, ++*mangled
);
3117 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
3118 string_append (declp
, buf
);
3119 string_append (declp
, method
);
3121 n
= strlen (*mangled
);
3130 else if (strncmp (*mangled
, "__t", 3) == 0
3131 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
3133 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
3139 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3142 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3145 success
= do_type (work
, mangled
, declp
);
3148 if (success
&& **mangled
!= '\0')
3151 string_append (declp
, p
);
3161 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
3162 string
*result
, int namelength
)
3164 char * recurse
= (char *)NULL
;
3165 char * recurse_dem
= (char *)NULL
;
3167 recurse
= XNEWVEC (char, namelength
+ 1);
3168 memcpy (recurse
, *mangled
, namelength
);
3169 recurse
[namelength
] = '\000';
3171 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3175 string_append (result
, recurse_dem
);
3180 string_appendn (result
, *mangled
, namelength
);
3183 *mangled
+= namelength
;
3190 arm_special -- special handling of ARM/lucid mangled strings
3195 arm_special (const char **mangled,
3201 Process some special ARM style mangling forms that don't fit
3202 the normal pattern. For example:
3204 __vtbl__3foo (foo virtual table)
3205 __vtbl__3foo__3bar (bar::foo virtual table)
3210 arm_special (const char **mangled
, string
*declp
)
3216 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3218 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3219 and create the decl. Note that we consume the entire mangled
3220 input string, which means that demangle_signature has no work
3222 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3223 while (*scan
!= '\0') /* first check it can be demangled */
3225 n
= consume_count (&scan
);
3228 return (0); /* no good */
3231 if (scan
[0] == '_' && scan
[1] == '_')
3236 (*mangled
) += ARM_VTABLE_STRLEN
;
3237 while (**mangled
!= '\0')
3239 n
= consume_count (mangled
);
3241 || n
> (long) strlen (*mangled
))
3243 string_prependn (declp
, *mangled
, n
);
3245 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3247 string_prepend (declp
, "::");
3251 string_append (declp
, " virtual table");
3264 demangle_qualified -- demangle 'Q' qualified name strings
3269 demangle_qualified (struct work_stuff *, const char *mangled,
3270 string *result, int isfuncname, int append);
3274 Demangle a qualified name, such as "Q25Outer5Inner" which is
3275 the mangled form of "Outer::Inner". The demangled output is
3276 prepended or appended to the result string according to the
3277 state of the append flag.
3279 If isfuncname is nonzero, then the qualified name we are building
3280 is going to be used as a member function name, so if it is a
3281 constructor or destructor function, append an appropriate
3282 constructor or destructor name. I.E. for the above example,
3283 the result for use as a constructor is "Outer::Inner::Inner"
3284 and the result for use as a destructor is "Outer::Inner::~Inner".
3288 Numeric conversion is ASCII dependent (FIXME).
3293 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3294 string
*result
, int isfuncname
, int append
)
3301 int bindex
= register_Btype (work
);
3303 /* We only make use of ISFUNCNAME if the entity is a constructor or
3305 isfuncname
= (isfuncname
3306 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3308 string_init (&temp
);
3309 string_init (&last_name
);
3311 if ((*mangled
)[0] == 'K')
3313 /* Squangling qualified name reuse */
3316 idx
= consume_count_with_underscores (mangled
);
3317 if (idx
== -1 || idx
>= work
-> numk
)
3320 string_append (&temp
, work
-> ktypevec
[idx
]);
3323 switch ((*mangled
)[1])
3326 /* GNU mangled name with more than 9 classes. The count is preceded
3327 by an underscore (to distinguish it from the <= 9 case) and followed
3328 by an underscore. */
3330 qualifiers
= consume_count_with_underscores (mangled
);
3331 if (qualifiers
== -1)
3344 /* The count is in a single digit. */
3345 num
[0] = (*mangled
)[1];
3347 qualifiers
= atoi (num
);
3349 /* If there is an underscore after the digit, skip it. This is
3350 said to be for ARM-qualified names, but the ARM makes no
3351 mention of such an underscore. Perhaps cfront uses one. */
3352 if ((*mangled
)[2] == '_')
3367 /* Pick off the names and collect them in the temp buffer in the order
3368 in which they are found, separated by '::'. */
3370 while (qualifiers
-- > 0)
3373 string_clear (&last_name
);
3375 if (*mangled
[0] == '_')
3378 if (*mangled
[0] == 't')
3380 /* Here we always append to TEMP since we will want to use
3381 the template name without the template parameters as a
3382 constructor or destructor name. The appropriate
3383 (parameter-less) value is returned by demangle_template
3384 in LAST_NAME. We do not remember the template type here,
3385 in order to match the G++ mangling algorithm. */
3386 success
= demangle_template(work
, mangled
, &temp
,
3391 else if (*mangled
[0] == 'K')
3395 idx
= consume_count_with_underscores (mangled
);
3396 if (idx
== -1 || idx
>= work
->numk
)
3399 string_append (&temp
, work
->ktypevec
[idx
]);
3402 if (!success
) break;
3409 /* Now recursively demangle the qualifier
3410 * This is necessary to deal with templates in
3411 * mangling styles like EDG */
3412 namelength
= consume_count (mangled
);
3413 if (namelength
== -1)
3418 recursively_demangle(work
, mangled
, &temp
, namelength
);
3422 string_delete (&last_name
);
3423 success
= do_type (work
, mangled
, &last_name
);
3426 string_appends (&temp
, &last_name
);
3431 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3434 string_append (&temp
, SCOPE_STRING (work
));
3437 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3439 /* If we are using the result as a function name, we need to append
3440 the appropriate '::' separated constructor or destructor name.
3441 We do this here because this is the most convenient place, where
3442 we already have a pointer to the name and the length of the name. */
3446 string_append (&temp
, SCOPE_STRING (work
));
3447 if (work
-> destructor
& 1)
3448 string_append (&temp
, "~");
3449 string_appends (&temp
, &last_name
);
3452 /* Now either prepend the temp buffer to the result, or append it,
3453 depending upon the state of the append flag. */
3456 string_appends (result
, &temp
);
3459 if (!STRING_EMPTY (result
))
3460 string_append (&temp
, SCOPE_STRING (work
));
3461 string_prepends (result
, &temp
);
3464 string_delete (&last_name
);
3465 string_delete (&temp
);
3473 get_count -- convert an ascii count to integer, consuming tokens
3478 get_count (const char **type, int *count)
3482 Assume that *type points at a count in a mangled name; set
3483 *count to its value, and set *type to the next character after
3484 the count. There are some weird rules in effect here.
3486 If *type does not point at a string of digits, return zero.
3488 If *type points at a string of digits followed by an
3489 underscore, set *count to their value as an integer, advance
3490 *type to point *after the underscore, and return 1.
3492 If *type points at a string of digits not followed by an
3493 underscore, consume only the first digit. Set *count to its
3494 value as an integer, leave *type pointing after that digit,
3497 The excuse for this odd behavior: in the ARM and HP demangling
3498 styles, a type can be followed by a repeat count of the form
3501 `x' is a single digit specifying how many additional copies
3502 of the type to append to the argument list, and
3504 `y' is one or more digits, specifying the zero-based index of
3505 the first repeated argument in the list. Yes, as you're
3506 unmangling the name you can figure this out yourself, but
3509 So, for example, in `bar__3fooFPiN51', the first argument is a
3510 pointer to an integer (`Pi'), and then the next five arguments
3511 are the same (`N5'), and the first repeat is the function's
3512 second argument (`1').
3516 get_count (const char **type
, int *count
)
3521 if (!ISDIGIT ((unsigned char)**type
))
3525 *count
= **type
- '0';
3527 if (ISDIGIT ((unsigned char)**type
))
3537 while (ISDIGIT ((unsigned char)*p
));
3548 /* RESULT will be initialised here; it will be freed on failure. The
3549 value returned is really a type_kind_t. */
3552 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3558 const char *remembered_type
;
3560 type_kind_t tk
= tk_none
;
3562 string_init (&decl
);
3563 string_init (result
);
3567 while (success
&& !done
)
3573 /* A pointer type */
3577 if (! (work
-> options
& DMGL_JAVA
))
3578 string_prepend (&decl
, "*");
3583 /* A reference type */
3586 string_prepend (&decl
, "&");
3595 if (!STRING_EMPTY (&decl
)
3596 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3598 string_prepend (&decl
, "(");
3599 string_append (&decl
, ")");
3601 string_append (&decl
, "[");
3602 if (**mangled
!= '_')
3603 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3605 if (**mangled
== '_')
3607 string_append (&decl
, "]");
3611 /* A back reference to a previously seen type */
3614 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3620 remembered_type
= work
-> typevec
[n
];
3621 mangled
= &remembered_type
;
3628 if (!STRING_EMPTY (&decl
)
3629 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3631 string_prepend (&decl
, "(");
3632 string_append (&decl
, ")");
3634 /* After picking off the function args, we expect to either find the
3635 function return type (preceded by an '_') or the end of the
3637 if (!demangle_nested_args (work
, mangled
, &decl
)
3638 || (**mangled
!= '_' && **mangled
!= '\0'))
3643 if (success
&& (**mangled
== '_'))
3650 type_quals
= TYPE_UNQUALIFIED
;
3652 member
= **mangled
== 'M';
3655 string_append (&decl
, ")");
3657 /* We don't need to prepend `::' for a qualified name;
3658 demangle_qualified will do that for us. */
3659 if (**mangled
!= 'Q')
3660 string_prepend (&decl
, SCOPE_STRING (work
));
3662 if (ISDIGIT ((unsigned char)**mangled
))
3664 n
= consume_count (mangled
);
3666 || (int) strlen (*mangled
) < n
)
3671 string_prependn (&decl
, *mangled
, n
);
3674 else if (**mangled
== 'X' || **mangled
== 'Y')
3677 do_type (work
, mangled
, &temp
);
3678 string_prepends (&decl
, &temp
);
3679 string_delete (&temp
);
3681 else if (**mangled
== 't')
3684 string_init (&temp
);
3685 success
= demangle_template (work
, mangled
, &temp
,
3689 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3690 string_delete (&temp
);
3694 string_delete (&temp
);
3698 else if (**mangled
== 'Q')
3700 success
= demangle_qualified (work
, mangled
, &decl
,
3712 string_prepend (&decl
, "(");
3720 type_quals
|= code_for_qualifier (**mangled
);
3728 if (*(*mangled
)++ != 'F')
3734 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3735 || **mangled
!= '_')
3741 if (! PRINT_ANSI_QUALIFIERS
)
3745 if (type_quals
!= TYPE_UNQUALIFIED
)
3747 APPEND_BLANK (&decl
);
3748 string_append (&decl
, qualifier_string (type_quals
));
3759 if (PRINT_ANSI_QUALIFIERS
)
3761 if (!STRING_EMPTY (&decl
))
3762 string_prepend (&decl
, " ");
3764 string_prepend (&decl
, demangle_qualifier (**mangled
));
3779 if (success
) switch (**mangled
)
3781 /* A qualified name, such as "Outer::Inner". */
3785 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3789 /* A back reference to a previously seen squangled type */
3792 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3795 string_append (result
, work
->btypevec
[n
]);
3800 /* A template parm. We substitute the corresponding argument. */
3805 idx
= consume_count_with_underscores (mangled
);
3808 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3809 || consume_count_with_underscores (mangled
) == -1)
3815 if (work
->tmpl_argvec
)
3816 string_append (result
, work
->tmpl_argvec
[idx
]);
3818 string_append_template_idx (result
, idx
);
3825 success
= demangle_fund_type (work
, mangled
, result
);
3827 tk
= (type_kind_t
) success
;
3833 if (!STRING_EMPTY (&decl
))
3835 string_append (result
, " ");
3836 string_appends (result
, &decl
);
3840 string_delete (result
);
3841 string_delete (&decl
);
3844 /* Assume an integral type, if we're not sure. */
3845 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3850 /* Given a pointer to a type string that represents a fundamental type
3851 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3852 string in which the demangled output is being built in RESULT, and
3853 the WORK structure, decode the types and add them to the result.
3858 "Sl" => "signed long"
3859 "CUs" => "const unsigned short"
3861 The value returned is really a type_kind_t. */
3864 demangle_fund_type (struct work_stuff
*work
,
3865 const char **mangled
, string
*result
)
3869 char buf
[INTBUF_SIZE
+ 5 /* 'int%u_t' */];
3870 unsigned int dec
= 0;
3871 type_kind_t tk
= tk_integral
;
3873 /* First pick off any type qualifiers. There can be more than one. */
3882 if (PRINT_ANSI_QUALIFIERS
)
3884 if (!STRING_EMPTY (result
))
3885 string_prepend (result
, " ");
3886 string_prepend (result
, demangle_qualifier (**mangled
));
3892 APPEND_BLANK (result
);
3893 string_append (result
, "unsigned");
3895 case 'S': /* signed char only */
3897 APPEND_BLANK (result
);
3898 string_append (result
, "signed");
3902 APPEND_BLANK (result
);
3903 string_append (result
, "__complex");
3911 /* Now pick off the fundamental type. There can be only one. */
3920 APPEND_BLANK (result
);
3921 string_append (result
, "void");
3925 APPEND_BLANK (result
);
3926 string_append (result
, "long long");
3930 APPEND_BLANK (result
);
3931 string_append (result
, "long");
3935 APPEND_BLANK (result
);
3936 string_append (result
, "int");
3940 APPEND_BLANK (result
);
3941 string_append (result
, "short");
3945 APPEND_BLANK (result
);
3946 string_append (result
, "bool");
3951 APPEND_BLANK (result
);
3952 string_append (result
, "char");
3957 APPEND_BLANK (result
);
3958 string_append (result
, "wchar_t");
3963 APPEND_BLANK (result
);
3964 string_append (result
, "long double");
3969 APPEND_BLANK (result
);
3970 string_append (result
, "double");
3975 APPEND_BLANK (result
);
3976 string_append (result
, "float");
3981 if (!ISDIGIT ((unsigned char)**mangled
))
3988 if (**mangled
== '_')
3993 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3996 if (**mangled
!= '_')
4006 strncpy (buf
, *mangled
, 2);
4008 *mangled
+= min (strlen (*mangled
), 2);
4010 sscanf (buf
, "%x", &dec
);
4011 sprintf (buf
, "int%u_t", dec
);
4012 APPEND_BLANK (result
);
4013 string_append (result
, buf
);
4017 /* An explicit type, such as "6mytype" or "7integer" */
4029 int bindex
= register_Btype (work
);
4031 string_init (&btype
);
4032 if (demangle_class_name (work
, mangled
, &btype
)) {
4033 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
4034 APPEND_BLANK (result
);
4035 string_appends (result
, &btype
);
4039 string_delete (&btype
);
4045 string_init (&btype
);
4046 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
4047 string_appends (result
, &btype
);
4048 string_delete (&btype
);
4056 return success
? ((int) tk
) : 0;
4060 /* Handle a template's value parameter for HP aCC (extension from ARM)
4061 **mangled points to 'S' or 'U' */
4064 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
4065 const char **mangled
, string
*result
)
4069 if (**mangled
!= 'U' && **mangled
!= 'S')
4072 unsigned_const
= (**mangled
== 'U');
4079 string_append (result
, "-");
4085 /* special case for -2^31 */
4086 string_append (result
, "-2147483648");
4093 /* We have to be looking at an integer now */
4094 if (!(ISDIGIT ((unsigned char)**mangled
)))
4097 /* We only deal with integral values for template
4098 parameters -- so it's OK to look only for digits */
4099 while (ISDIGIT ((unsigned char)**mangled
))
4101 char_str
[0] = **mangled
;
4102 string_append (result
, char_str
);
4107 string_append (result
, "U");
4109 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4110 with L or LL suffixes. pai/1997-09-03 */
4112 return 1; /* success */
4115 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4116 **mangled is pointing to the 'A' */
4119 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
4122 int literal_len
= 0;
4126 if (**mangled
!= 'A')
4131 literal_len
= consume_count (mangled
);
4133 if (literal_len
<= 0)
4136 /* Literal parameters are names of arrays, functions, etc. and the
4137 canonical representation uses the address operator */
4138 string_append (result
, "&");
4140 /* Now recursively demangle the literal name */
4141 recurse
= XNEWVEC (char, literal_len
+ 1);
4142 memcpy (recurse
, *mangled
, literal_len
);
4143 recurse
[literal_len
] = '\000';
4145 recurse_dem
= cplus_demangle (recurse
, work
->options
);
4149 string_append (result
, recurse_dem
);
4154 string_appendn (result
, *mangled
, literal_len
);
4156 (*mangled
) += literal_len
;
4163 snarf_numeric_literal (const char **args
, string
*arg
)
4168 string_append (arg
, char_str
);
4171 else if (**args
== '+')
4174 if (!ISDIGIT ((unsigned char)**args
))
4177 while (ISDIGIT ((unsigned char)**args
))
4179 char_str
[0] = **args
;
4180 string_append (arg
, char_str
);
4187 /* Demangle the next argument, given by MANGLED into RESULT, which
4188 *should be an uninitialized* string. It will be initialized here,
4189 and free'd should anything go wrong. */
4192 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4194 /* Remember where we started so that we can record the type, for
4195 non-squangling type remembering. */
4196 const char *start
= *mangled
;
4198 string_init (result
);
4200 if (work
->nrepeats
> 0)
4204 if (work
->previous_argument
== 0)
4207 /* We want to reissue the previous type in this argument list. */
4208 string_appends (result
, work
->previous_argument
);
4212 if (**mangled
== 'n')
4214 /* A squangling-style repeat. */
4216 work
->nrepeats
= consume_count(mangled
);
4218 if (work
->nrepeats
<= 0)
4219 /* This was not a repeat count after all. */
4222 if (work
->nrepeats
> 9)
4224 if (**mangled
!= '_')
4225 /* The repeat count should be followed by an '_' in this
4232 /* Now, the repeat is all set up. */
4233 return do_arg (work
, mangled
, result
);
4236 /* Save the result in WORK->previous_argument so that we can find it
4237 if it's repeated. Note that saving START is not good enough: we
4238 do not want to add additional types to the back-referenceable
4239 type vector when processing a repeated type. */
4240 if (work
->previous_argument
)
4241 string_delete (work
->previous_argument
);
4243 work
->previous_argument
= XNEW (string
);
4245 if (!do_type (work
, mangled
, work
->previous_argument
))
4248 string_appends (result
, work
->previous_argument
);
4250 remember_type (work
, start
, *mangled
- start
);
4255 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4259 if (work
->forgetting_types
)
4262 if (work
-> ntypes
>= work
-> typevec_size
)
4264 if (work
-> typevec_size
== 0)
4266 work
-> typevec_size
= 3;
4267 work
-> typevec
= XNEWVEC (char *, work
->typevec_size
);
4271 if (work
-> typevec_size
> INT_MAX
/ 2)
4272 xmalloc_failed (INT_MAX
);
4273 work
-> typevec_size
*= 2;
4275 = XRESIZEVEC (char *, work
->typevec
, work
->typevec_size
);
4278 tem
= XNEWVEC (char, len
+ 1);
4279 memcpy (tem
, start
, len
);
4281 work
-> typevec
[work
-> ntypes
++] = tem
;
4285 /* Remember a K type class qualifier. */
4287 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4291 if (work
-> numk
>= work
-> ksize
)
4293 if (work
-> ksize
== 0)
4296 work
-> ktypevec
= XNEWVEC (char *, work
->ksize
);
4300 if (work
-> ksize
> INT_MAX
/ 2)
4301 xmalloc_failed (INT_MAX
);
4304 = XRESIZEVEC (char *, work
->ktypevec
, work
->ksize
);
4307 tem
= XNEWVEC (char, len
+ 1);
4308 memcpy (tem
, start
, len
);
4310 work
-> ktypevec
[work
-> numk
++] = tem
;
4313 /* Register a B code, and get an index for it. B codes are registered
4314 as they are seen, rather than as they are completed, so map<temp<char> >
4315 registers map<temp<char> > as B0, and temp<char> as B1 */
4318 register_Btype (struct work_stuff
*work
)
4322 if (work
-> numb
>= work
-> bsize
)
4324 if (work
-> bsize
== 0)
4327 work
-> btypevec
= XNEWVEC (char *, work
->bsize
);
4331 if (work
-> bsize
> INT_MAX
/ 2)
4332 xmalloc_failed (INT_MAX
);
4335 = XRESIZEVEC (char *, work
->btypevec
, work
->bsize
);
4338 ret
= work
-> numb
++;
4339 work
-> btypevec
[ret
] = NULL
;
4343 /* Store a value into a previously registered B code type. */
4346 remember_Btype (struct work_stuff
*work
, const char *start
,
4351 tem
= XNEWVEC (char, len
+ 1);
4352 memcpy (tem
, start
, len
);
4354 work
-> btypevec
[index
] = tem
;
4357 /* Lose all the info related to B and K type codes. */
4359 forget_B_and_K_types (struct work_stuff
*work
)
4363 while (work
-> numk
> 0)
4365 i
= --(work
-> numk
);
4366 if (work
-> ktypevec
[i
] != NULL
)
4368 free (work
-> ktypevec
[i
]);
4369 work
-> ktypevec
[i
] = NULL
;
4373 while (work
-> numb
> 0)
4375 i
= --(work
-> numb
);
4376 if (work
-> btypevec
[i
] != NULL
)
4378 free (work
-> btypevec
[i
]);
4379 work
-> btypevec
[i
] = NULL
;
4383 /* Forget the remembered types, but not the type vector itself. */
4386 forget_types (struct work_stuff
*work
)
4390 while (work
-> ntypes
> 0)
4392 i
= --(work
-> ntypes
);
4393 if (work
-> typevec
[i
] != NULL
)
4395 free (work
-> typevec
[i
]);
4396 work
-> typevec
[i
] = NULL
;
4401 /* Process the argument list part of the signature, after any class spec
4402 has been consumed, as well as the first 'F' character (if any). For
4405 "__als__3fooRT0" => process "RT0"
4406 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4408 DECLP must be already initialised, usually non-empty. It won't be freed
4411 Note that g++ differs significantly from ARM and lucid style mangling
4412 with regards to references to previously seen types. For example, given
4413 the source fragment:
4417 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4420 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4421 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4423 g++ produces the names:
4428 while lcc (and presumably other ARM style compilers as well) produces:
4430 foo__FiR3fooT1T2T1T2
4431 __ct__3fooFiR3fooT1T2T1T2
4433 Note that g++ bases its type numbers starting at zero and counts all
4434 previously seen types, while lucid/ARM bases its type numbers starting
4435 at one and only considers types after it has seen the 'F' character
4436 indicating the start of the function args. For lucid/ARM style, we
4437 account for this difference by discarding any previously seen types when
4438 we see the 'F' character, and subtracting one from the type number
4444 demangle_args (struct work_stuff
*work
, const char **mangled
,
4454 if (PRINT_ARG_TYPES
)
4456 string_append (declp
, "(");
4457 if (**mangled
== '\0')
4459 string_append (declp
, "void");
4463 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4464 || work
->nrepeats
> 0)
4466 if ((**mangled
== 'N') || (**mangled
== 'T'))
4468 temptype
= *(*mangled
)++;
4470 if (temptype
== 'N')
4472 if (!get_count (mangled
, &r
))
4481 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4483 /* If we have 10 or more types we might have more than a 1 digit
4484 index so we'll have to consume the whole count here. This
4485 will lose if the next thing is a type name preceded by a
4486 count but it's impossible to demangle that case properly
4487 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4488 Pc, ...)" or "(..., type12, char *, ...)" */
4489 if ((t
= consume_count(mangled
)) <= 0)
4496 if (!get_count (mangled
, &t
))
4501 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4505 /* Validate the type index. Protect against illegal indices from
4506 malformed type strings. */
4507 if ((t
< 0) || (t
>= work
-> ntypes
))
4511 while (work
->nrepeats
> 0 || --r
>= 0)
4513 tem
= work
-> typevec
[t
];
4514 if (need_comma
&& PRINT_ARG_TYPES
)
4516 string_append (declp
, ", ");
4518 if (!do_arg (work
, &tem
, &arg
))
4522 if (PRINT_ARG_TYPES
)
4524 string_appends (declp
, &arg
);
4526 string_delete (&arg
);
4532 if (need_comma
&& PRINT_ARG_TYPES
)
4533 string_append (declp
, ", ");
4534 if (!do_arg (work
, mangled
, &arg
))
4536 if (PRINT_ARG_TYPES
)
4537 string_appends (declp
, &arg
);
4538 string_delete (&arg
);
4543 if (**mangled
== 'e')
4546 if (PRINT_ARG_TYPES
)
4550 string_append (declp
, ",");
4552 string_append (declp
, "...");
4556 if (PRINT_ARG_TYPES
)
4558 string_append (declp
, ")");
4563 /* Like demangle_args, but for demangling the argument lists of function
4564 and method pointers or references, not top-level declarations. */
4567 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4570 string
* saved_previous_argument
;
4574 /* The G++ name-mangling algorithm does not remember types on nested
4575 argument lists, unless -fsquangling is used, and in that case the
4576 type vector updated by remember_type is not used. So, we turn
4577 off remembering of types here. */
4578 ++work
->forgetting_types
;
4580 /* For the repeat codes used with -fsquangling, we must keep track of
4581 the last argument. */
4582 saved_previous_argument
= work
->previous_argument
;
4583 saved_nrepeats
= work
->nrepeats
;
4584 work
->previous_argument
= 0;
4587 /* Actually demangle the arguments. */
4588 result
= demangle_args (work
, mangled
, declp
);
4590 /* Restore the previous_argument field. */
4591 if (work
->previous_argument
)
4593 string_delete (work
->previous_argument
);
4594 free ((char *) work
->previous_argument
);
4596 work
->previous_argument
= saved_previous_argument
;
4597 --work
->forgetting_types
;
4598 work
->nrepeats
= saved_nrepeats
;
4603 /* Returns 1 if a valid function name was found or 0 otherwise. */
4606 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4607 string
*declp
, const char *scan
)
4613 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4614 string_need (declp
, 1);
4615 *(declp
-> p
) = '\0';
4617 /* Consume the function name, including the "__" separating the name
4618 from the signature. We are guaranteed that SCAN points to the
4621 (*mangled
) = scan
+ 2;
4622 /* We may be looking at an instantiation of a template function:
4623 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4624 following _F marks the start of the function arguments. Handle
4625 the template arguments first. */
4627 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4629 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4630 /* This leaves MANGLED pointing to the 'F' marking func args */
4633 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4636 /* See if we have an ARM style constructor or destructor operator.
4637 If so, then just record it, clear the decl, and return.
4638 We can't build the actual constructor/destructor decl until later,
4639 when we recover the class name from the signature. */
4641 if (strcmp (declp
-> b
, "__ct") == 0)
4643 work
-> constructor
+= 1;
4644 string_clear (declp
);
4647 else if (strcmp (declp
-> b
, "__dt") == 0)
4649 work
-> destructor
+= 1;
4650 string_clear (declp
);
4655 if (declp
->p
- declp
->b
>= 3
4656 && declp
->b
[0] == 'o'
4657 && declp
->b
[1] == 'p'
4658 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4660 /* see if it's an assignment expression */
4661 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4662 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4664 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4666 int len
= declp
->p
- declp
->b
- 10;
4667 if ((int) strlen (optable
[i
].in
) == len
4668 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4670 string_clear (declp
);
4671 string_append (declp
, "operator");
4672 string_append (declp
, optable
[i
].out
);
4673 string_append (declp
, "=");
4680 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4682 int len
= declp
->p
- declp
->b
- 3;
4683 if ((int) strlen (optable
[i
].in
) == len
4684 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4686 string_clear (declp
);
4687 string_append (declp
, "operator");
4688 string_append (declp
, optable
[i
].out
);
4694 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4695 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4697 /* type conversion operator */
4699 if (do_type (work
, &tem
, &type
))
4701 string_clear (declp
);
4702 string_append (declp
, "operator ");
4703 string_appends (declp
, &type
);
4704 string_delete (&type
);
4707 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4708 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4711 /* type conversion operator. */
4713 if (do_type (work
, &tem
, &type
))
4715 string_clear (declp
);
4716 string_append (declp
, "operator ");
4717 string_appends (declp
, &type
);
4718 string_delete (&type
);
4721 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4722 && ISLOWER((unsigned char)declp
->b
[2])
4723 && ISLOWER((unsigned char)declp
->b
[3]))
4725 if (declp
->b
[4] == '\0')
4728 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4730 if (strlen (optable
[i
].in
) == 2
4731 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4733 string_clear (declp
);
4734 string_append (declp
, "operator");
4735 string_append (declp
, optable
[i
].out
);
4742 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4745 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4747 if (strlen (optable
[i
].in
) == 3
4748 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4750 string_clear (declp
);
4751 string_append (declp
, "operator");
4752 string_append (declp
, optable
[i
].out
);
4760 /* If a function name was obtained but it's not valid, we were not
4762 if (LEN_STRING (declp
) == 1 && declp
->b
[0] == '.')
4768 /* a mini string-handling package */
4771 string_need (string
*s
, int n
)
4781 s
->p
= s
->b
= XNEWVEC (char, n
);
4784 else if (s
->e
- s
->p
< n
)
4787 if (n
> INT_MAX
/ 2 - tem
)
4788 xmalloc_failed (INT_MAX
);
4791 s
->b
= XRESIZEVEC (char, s
->b
, n
);
4798 string_delete (string
*s
)
4803 s
->b
= s
->e
= s
->p
= NULL
;
4808 string_init (string
*s
)
4810 s
->b
= s
->p
= s
->e
= NULL
;
4814 string_clear (string
*s
)
4822 string_empty (string
*s
)
4824 return (s
->b
== s
->p
);
4830 string_append (string
*p
, const char *s
)
4833 if (s
== NULL
|| *s
== '\0')
4837 memcpy (p
->p
, s
, n
);
4842 string_appends (string
*p
, string
*s
)
4850 memcpy (p
->p
, s
->b
, n
);
4856 string_appendn (string
*p
, const char *s
, int n
)
4861 memcpy (p
->p
, s
, n
);
4867 string_prepend (string
*p
, const char *s
)
4869 if (s
!= NULL
&& *s
!= '\0')
4871 string_prependn (p
, s
, strlen (s
));
4876 string_prepends (string
*p
, string
*s
)
4880 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4885 string_prependn (string
*p
, const char *s
, int n
)
4892 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4896 memcpy (p
->b
, s
, n
);
4902 string_append_template_idx (string
*s
, int idx
)
4904 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4905 sprintf(buf
, "T%d", idx
);
4906 string_append (s
, buf
);