1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 Libiberty is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with libiberty; see the file COPYING.LIB. If
20 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
25 This file imports xmalloc and xrealloc, which are like malloc and
26 realloc except that they generate a fatal error if there is no
29 /* This file lives in both GCC and libiberty. When making changes, please
30 try not to break either. */
37 #include <sys/types.h>
49 #undef CURRENT_DEMANGLING_STYLE
50 #define CURRENT_DEMANGLING_STYLE work->options
52 #include "libiberty.h"
54 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
56 /* A value at least one greater than the maximum number of characters
57 that will be output when using the `%d' format with `printf'. */
58 #define INTBUF_SIZE 32
60 extern void fancy_abort
PARAMS ((void)) ATTRIBUTE_NORETURN
;
62 static const char *mystrstr
PARAMS ((const char *, const char *));
68 register const char *p
= s1
;
69 register int len
= strlen (s2
);
71 for (; (p
= strchr (p
, *s2
)) != 0; p
++)
73 if (strncmp (p
, s2
, len
) == 0)
81 /* In order to allow a single demangler executable to demangle strings
82 using various common values of CPLUS_MARKER, as well as any specific
83 one set at compile time, we maintain a string containing all the
84 commonly used ones, and check to see if the marker we are looking for
85 is in that string. CPLUS_MARKER is usually '$' on systems where the
86 assembler can deal with that. Where the assembler can't, it's usually
87 '.' (but on many systems '.' is used for other things). We put the
88 current defined CPLUS_MARKER first (which defaults to '$'), followed
89 by the next most common value, followed by an explicit '$' in case
90 the value of CPLUS_MARKER is not '$'.
92 We could avoid this if we could just get g++ to tell us what the actual
93 cplus marker character is as part of the debug information, perhaps by
94 ensuring that it is the character that terminates the gcc<n>_compiled
95 marker symbol (FIXME). */
97 #if !defined (CPLUS_MARKER)
98 #define CPLUS_MARKER '$'
101 enum demangling_styles current_demangling_style
= gnu_demangling
;
103 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
105 static char char_str
[2] = { '\000', '\000' };
108 set_cplus_marker_for_demangling (ch
)
111 cplus_markers
[0] = ch
;
114 typedef struct string
/* Beware: these aren't required to be */
115 { /* '\0' terminated. */
116 char *b
; /* pointer to start of string */
117 char *p
; /* pointer after last character */
118 char *e
; /* pointer after end of allocated space */
121 /* Stuff that is shared between sub-routines.
122 Using a shared structure allows cplus_demangle to be reentrant. */
138 int static_type
; /* A static member function */
139 int temp_start
; /* index in demangled to start of template args */
140 int type_quals
; /* The type qualifiers. */
141 int dllimported
; /* Symbol imported from a PE DLL */
142 char **tmpl_argvec
; /* Template function arguments. */
143 int ntmpl_args
; /* The number of template function arguments. */
144 int forgetting_types
; /* Nonzero if we are not remembering the types
146 string
* previous_argument
; /* The last function argument demangled. */
147 int nrepeats
; /* The number of times to repeat the previous
151 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
152 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
154 static const struct optable
160 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
161 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
162 {"new", " new", 0}, /* old (1.91, and 1.x) */
163 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
164 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
165 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
166 {"as", "=", DMGL_ANSI
}, /* ansi */
167 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
168 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
169 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
170 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
171 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
172 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
173 {"plus", "+", 0}, /* old */
174 {"pl", "+", DMGL_ANSI
}, /* ansi */
175 {"apl", "+=", DMGL_ANSI
}, /* ansi */
176 {"minus", "-", 0}, /* old */
177 {"mi", "-", DMGL_ANSI
}, /* ansi */
178 {"ami", "-=", DMGL_ANSI
}, /* ansi */
179 {"mult", "*", 0}, /* old */
180 {"ml", "*", DMGL_ANSI
}, /* ansi */
181 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
182 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
183 {"convert", "+", 0}, /* old (unary +) */
184 {"negate", "-", 0}, /* old (unary -) */
185 {"trunc_mod", "%", 0}, /* old */
186 {"md", "%", DMGL_ANSI
}, /* ansi */
187 {"amd", "%=", DMGL_ANSI
}, /* ansi */
188 {"trunc_div", "/", 0}, /* old */
189 {"dv", "/", DMGL_ANSI
}, /* ansi */
190 {"adv", "/=", DMGL_ANSI
}, /* ansi */
191 {"truth_andif", "&&", 0}, /* old */
192 {"aa", "&&", DMGL_ANSI
}, /* ansi */
193 {"truth_orif", "||", 0}, /* old */
194 {"oo", "||", DMGL_ANSI
}, /* ansi */
195 {"truth_not", "!", 0}, /* old */
196 {"nt", "!", DMGL_ANSI
}, /* ansi */
197 {"postincrement","++", 0}, /* old */
198 {"pp", "++", DMGL_ANSI
}, /* ansi */
199 {"postdecrement","--", 0}, /* old */
200 {"mm", "--", DMGL_ANSI
}, /* ansi */
201 {"bit_ior", "|", 0}, /* old */
202 {"or", "|", DMGL_ANSI
}, /* ansi */
203 {"aor", "|=", DMGL_ANSI
}, /* ansi */
204 {"bit_xor", "^", 0}, /* old */
205 {"er", "^", DMGL_ANSI
}, /* ansi */
206 {"aer", "^=", DMGL_ANSI
}, /* ansi */
207 {"bit_and", "&", 0}, /* old */
208 {"ad", "&", DMGL_ANSI
}, /* ansi */
209 {"aad", "&=", DMGL_ANSI
}, /* ansi */
210 {"bit_not", "~", 0}, /* old */
211 {"co", "~", DMGL_ANSI
}, /* ansi */
212 {"call", "()", 0}, /* old */
213 {"cl", "()", DMGL_ANSI
}, /* ansi */
214 {"alshift", "<<", 0}, /* old */
215 {"ls", "<<", DMGL_ANSI
}, /* ansi */
216 {"als", "<<=", DMGL_ANSI
}, /* ansi */
217 {"arshift", ">>", 0}, /* old */
218 {"rs", ">>", DMGL_ANSI
}, /* ansi */
219 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
220 {"component", "->", 0}, /* old */
221 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
222 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
223 {"indirect", "*", 0}, /* old */
224 {"method_call", "->()", 0}, /* old */
225 {"addr", "&", 0}, /* old (unary &) */
226 {"array", "[]", 0}, /* old */
227 {"vc", "[]", DMGL_ANSI
}, /* ansi */
228 {"compound", ", ", 0}, /* old */
229 {"cm", ", ", DMGL_ANSI
}, /* ansi */
230 {"cond", "?:", 0}, /* old */
231 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
232 {"max", ">?", 0}, /* old */
233 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
234 {"min", "<?", 0}, /* old */
235 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
236 {"nop", "", 0}, /* old (for operator=) */
237 {"rm", "->*", DMGL_ANSI
}, /* ansi */
238 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
241 /* These values are used to indicate the various type varieties.
242 They are all non-zero so that they can be used as `success'
244 typedef enum type_kind_t
255 struct demangler_engine libiberty_demanglers
[] =
258 AUTO_DEMANGLING_STYLE_STRING
,
260 "Automatic selection based on executable"
264 GNU_DEMANGLING_STYLE_STRING
,
266 "GNU (g++) style demangling"
270 LUCID_DEMANGLING_STYLE_STRING
,
272 "Lucid (lcc) style demangling"
276 ARM_DEMANGLING_STYLE_STRING
,
278 "ARM style demangling"
282 HP_DEMANGLING_STYLE_STRING
,
284 "HP (aCC) style demangling"
288 EDG_DEMANGLING_STYLE_STRING
,
290 "EDG style demangling"
294 NULL
, unknown_demangling
, NULL
298 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
299 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
300 string_prepend(str, " ");}
301 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
302 string_append(str, " ");}
303 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
305 /* The scope separator appropriate for the language being demangled. */
307 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
309 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
310 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
312 /* Prototypes for local functions */
315 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
318 squangle_mop_up
PARAMS ((struct work_stuff
*));
322 demangle_method_args
PARAMS ((struct work_stuff
*, const char **, string
*));
326 internal_cplus_demangle
PARAMS ((struct work_stuff
*, const char *));
329 demangle_template_template_parm
PARAMS ((struct work_stuff
*work
,
330 const char **, string
*));
333 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*,
334 string
*, int, int));
337 arm_pt
PARAMS ((struct work_stuff
*, const char *, int, const char **,
341 demangle_class_name
PARAMS ((struct work_stuff
*, const char **, string
*));
344 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
348 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
351 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
354 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
357 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
360 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
363 arm_special
PARAMS ((const char **, string
*));
366 string_need
PARAMS ((string
*, int));
369 string_delete
PARAMS ((string
*));
372 string_init
PARAMS ((string
*));
375 string_clear
PARAMS ((string
*));
379 string_empty
PARAMS ((string
*));
383 string_append
PARAMS ((string
*, const char *));
386 string_appends
PARAMS ((string
*, string
*));
389 string_appendn
PARAMS ((string
*, const char *, int));
392 string_prepend
PARAMS ((string
*, const char *));
395 string_prependn
PARAMS ((string
*, const char *, int));
398 string_append_template_idx
PARAMS ((string
*, int));
401 get_count
PARAMS ((const char **, int *));
404 consume_count
PARAMS ((const char **));
407 consume_count_with_underscores
PARAMS ((const char**));
410 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
413 demangle_nested_args
PARAMS ((struct work_stuff
*, const char**, string
*));
416 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
419 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
422 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
426 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
429 remember_Btype
PARAMS ((struct work_stuff
*, const char *, int, int));
432 register_Btype
PARAMS ((struct work_stuff
*));
435 remember_Ktype
PARAMS ((struct work_stuff
*, const char *, int));
438 forget_types
PARAMS ((struct work_stuff
*));
441 forget_B_and_K_types
PARAMS ((struct work_stuff
*));
444 string_prepends
PARAMS ((string
*, string
*));
447 demangle_template_value_parm
PARAMS ((struct work_stuff
*, const char**,
448 string
*, type_kind_t
));
451 do_hpacc_template_const_value
PARAMS ((struct work_stuff
*, const char **, string
*));
454 do_hpacc_template_literal
PARAMS ((struct work_stuff
*, const char **, string
*));
457 snarf_numeric_literal
PARAMS ((const char **, string
*));
459 /* There is a TYPE_QUAL value for each type qualifier. They can be
460 combined by bitwise-or to form the complete set of qualifiers for a
463 #define TYPE_UNQUALIFIED 0x0
464 #define TYPE_QUAL_CONST 0x1
465 #define TYPE_QUAL_VOLATILE 0x2
466 #define TYPE_QUAL_RESTRICT 0x4
469 code_for_qualifier
PARAMS ((int));
472 qualifier_string
PARAMS ((int));
475 demangle_qualifier
PARAMS ((int));
478 demangle_expression
PARAMS ((struct work_stuff
*, const char **, string
*,
482 demangle_integral_value
PARAMS ((struct work_stuff
*, const char **,
486 demangle_real_value
PARAMS ((struct work_stuff
*, const char **, string
*));
489 demangle_arm_hp_template
PARAMS ((struct work_stuff
*, const char **, int,
493 recursively_demangle
PARAMS ((struct work_stuff
*, const char **, string
*,
496 /* Translate count to integer, consuming tokens in the process.
497 Conversion terminates on the first non-digit character.
499 Trying to consume something that isn't a count results in no
500 consumption of input and a return of -1.
502 Overflow consumes the rest of the digits, and returns -1. */
510 if (! isdigit ((unsigned char)**type
))
513 while (isdigit ((unsigned char)**type
))
517 /* Check for overflow.
518 We assume that count is represented using two's-complement;
519 no power of two is divisible by ten, so if an overflow occurs
520 when multiplying by ten, the result will not be a multiple of
522 if ((count
% 10) != 0)
524 while (isdigit ((unsigned char) **type
))
529 count
+= **type
- '0';
537 /* Like consume_count, but for counts that are preceded and followed
538 by '_' if they are greater than 10. Also, -1 is returned for
539 failure, since 0 can be a valid value. */
542 consume_count_with_underscores (mangled
)
543 const char **mangled
;
547 if (**mangled
== '_')
550 if (!isdigit ((unsigned char)**mangled
))
553 idx
= consume_count (mangled
);
554 if (**mangled
!= '_')
555 /* The trailing underscore was missing. */
562 if (**mangled
< '0' || **mangled
> '9')
565 idx
= **mangled
- '0';
572 /* C is the code for a type-qualifier. Return the TYPE_QUAL
573 corresponding to this qualifier. */
576 code_for_qualifier (c
)
582 return TYPE_QUAL_CONST
;
585 return TYPE_QUAL_VOLATILE
;
588 return TYPE_QUAL_RESTRICT
;
594 /* C was an invalid qualifier. */
598 /* Return the string corresponding to the qualifiers given by
602 qualifier_string (type_quals
)
607 case TYPE_UNQUALIFIED
:
610 case TYPE_QUAL_CONST
:
613 case TYPE_QUAL_VOLATILE
:
616 case TYPE_QUAL_RESTRICT
:
619 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
620 return "const volatile";
622 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
623 return "const __restrict";
625 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
626 return "volatile __restrict";
628 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
629 return "const volatile __restrict";
635 /* TYPE_QUALS was an invalid qualifier set. */
639 /* C is the code for a type-qualifier. Return the string
640 corresponding to this qualifier. This function should only be
641 called with a valid qualifier code. */
644 demangle_qualifier (c
)
647 return qualifier_string (code_for_qualifier (c
));
651 cplus_demangle_opname (opname
, result
, options
)
658 struct work_stuff work
[1];
661 len
= strlen(opname
);
664 memset ((char *) work
, 0, sizeof (work
));
665 work
->options
= options
;
667 if (opname
[0] == '_' && opname
[1] == '_'
668 && opname
[2] == 'o' && opname
[3] == 'p')
671 /* type conversion operator. */
673 if (do_type (work
, &tem
, &type
))
675 strcat (result
, "operator ");
676 strncat (result
, type
.b
, type
.p
- type
.b
);
677 string_delete (&type
);
681 else if (opname
[0] == '_' && opname
[1] == '_'
682 && islower(opname
[2])
683 && islower(opname
[3]))
685 if (opname
[4] == '\0')
689 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
691 if (strlen (optable
[i
].in
) == 2
692 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
694 strcat (result
, "operator");
695 strcat (result
, optable
[i
].out
);
703 if (opname
[2] == 'a' && opname
[5] == '\0')
707 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
709 if (strlen (optable
[i
].in
) == 3
710 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
712 strcat (result
, "operator");
713 strcat (result
, optable
[i
].out
);
724 && strchr (cplus_markers
, opname
[2]) != NULL
)
726 /* see if it's an assignment expression */
727 if (len
>= 10 /* op$assign_ */
728 && memcmp (opname
+ 3, "assign_", 7) == 0)
731 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
734 if ((int) strlen (optable
[i
].in
) == len1
735 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
737 strcat (result
, "operator");
738 strcat (result
, optable
[i
].out
);
739 strcat (result
, "=");
748 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
751 if ((int) strlen (optable
[i
].in
) == len1
752 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
754 strcat (result
, "operator");
755 strcat (result
, optable
[i
].out
);
762 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
763 && strchr (cplus_markers
, opname
[4]) != NULL
)
765 /* type conversion operator */
767 if (do_type (work
, &tem
, &type
))
769 strcat (result
, "operator ");
770 strncat (result
, type
.b
, type
.p
- type
.b
);
771 string_delete (&type
);
775 squangle_mop_up (work
);
780 /* Takes operator name as e.g. "++" and returns mangled
781 operator name (e.g. "postincrement_expr"), or NULL if not found.
783 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
784 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
787 cplus_mangle_opname (opname
, options
)
794 len
= strlen (opname
);
795 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
797 if ((int) strlen (optable
[i
].out
) == len
798 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
799 && memcmp (optable
[i
].out
, opname
, len
) == 0)
800 return optable
[i
].in
;
805 /* Add a routine to set the demangling style to be sure it is valid and
806 allow for any demangler initialization that maybe necessary. */
808 enum demangling_styles
809 cplus_demangle_set_style (style
)
810 enum demangling_styles style
;
812 struct demangler_engine
*demangler
= libiberty_demanglers
;
814 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
815 if (style
== demangler
->demangling_style
)
817 current_demangling_style
= style
;
818 return current_demangling_style
;
821 return unknown_demangling
;
824 /* Do string name to style translation */
826 enum demangling_styles
827 cplus_demangle_name_to_style (name
)
830 struct demangler_engine
*demangler
= libiberty_demanglers
;
832 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
833 if (strcmp (name
, demangler
->demangling_style_name
) == 0)
834 return demangler
->demangling_style
;
836 return unknown_demangling
;
839 /* char *cplus_demangle (const char *mangled, int options)
841 If MANGLED is a mangled function name produced by GNU C++, then
842 a pointer to a malloced string giving a C++ representation
843 of the name will be returned; otherwise NULL will be returned.
844 It is the caller's responsibility to free the string which
847 The OPTIONS arg may contain one or more of the following bits:
849 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
851 DMGL_PARAMS Function parameters are included.
855 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
856 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
857 cplus_demangle ("foo__1Ai", 0) => "A::foo"
859 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
860 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
861 cplus_demangle ("foo__1Afe", 0) => "A::foo"
863 Note that any leading underscores, or other such characters prepended by
864 the compilation system, are presumed to have already been stripped from
868 cplus_demangle (mangled
, options
)
873 struct work_stuff work
[1];
874 memset ((char *) work
, 0, sizeof (work
));
875 work
-> options
= options
;
876 if ((work
-> options
& DMGL_STYLE_MASK
) == 0)
877 work
-> options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
879 ret
= internal_cplus_demangle (work
, mangled
);
880 squangle_mop_up (work
);
885 /* This function performs most of what cplus_demangle use to do, but
886 to be able to demangle a name with a B, K or n code, we need to
887 have a longer term memory of what types have been seen. The original
888 now intializes and cleans up the squangle code info, while internal
889 calls go directly to this routine to avoid resetting that info. */
892 internal_cplus_demangle (work
, mangled
)
893 struct work_stuff
*work
;
899 char *demangled
= NULL
;
901 s1
= work
->constructor
;
902 s2
= work
->destructor
;
903 s3
= work
->static_type
;
904 s4
= work
->type_quals
;
905 work
->constructor
= work
->destructor
= 0;
906 work
->type_quals
= TYPE_UNQUALIFIED
;
907 work
->dllimported
= 0;
909 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
913 /* First check to see if gnu style demangling is active and if the
914 string to be demangled contains a CPLUS_MARKER. If so, attempt to
915 recognize one of the gnu special forms rather than looking for a
916 standard prefix. In particular, don't worry about whether there
917 is a "__" string in the mangled string. Consider "_$_5__foo" for
920 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
922 success
= gnu_special (work
, &mangled
, &decl
);
926 success
= demangle_prefix (work
, &mangled
, &decl
);
928 if (success
&& (*mangled
!= '\0'))
930 success
= demangle_signature (work
, &mangled
, &decl
);
932 if (work
->constructor
== 2)
934 string_prepend (&decl
, "global constructors keyed to ");
935 work
->constructor
= 0;
937 else if (work
->destructor
== 2)
939 string_prepend (&decl
, "global destructors keyed to ");
940 work
->destructor
= 0;
942 else if (work
->dllimported
== 1)
944 string_prepend (&decl
, "import stub for ");
945 work
->dllimported
= 0;
947 demangled
= mop_up (work
, &decl
, success
);
949 work
->constructor
= s1
;
950 work
->destructor
= s2
;
951 work
->static_type
= s3
;
952 work
->type_quals
= s4
;
957 /* Clear out and squangling related storage */
959 squangle_mop_up (work
)
960 struct work_stuff
*work
;
962 /* clean up the B and K type mangling types. */
963 forget_B_and_K_types (work
);
964 if (work
-> btypevec
!= NULL
)
966 free ((char *) work
-> btypevec
);
968 if (work
-> ktypevec
!= NULL
)
970 free ((char *) work
-> ktypevec
);
974 /* Clear out any mangled storage */
977 mop_up (work
, declp
, success
)
978 struct work_stuff
*work
;
982 char *demangled
= NULL
;
984 /* Discard the remembered types, if any. */
987 if (work
-> typevec
!= NULL
)
989 free ((char *) work
-> typevec
);
990 work
-> typevec
= NULL
;
991 work
-> typevec_size
= 0;
993 if (work
->tmpl_argvec
)
997 for (i
= 0; i
< work
->ntmpl_args
; i
++)
998 if (work
->tmpl_argvec
[i
])
999 free ((char*) work
->tmpl_argvec
[i
]);
1001 free ((char*) work
->tmpl_argvec
);
1002 work
->tmpl_argvec
= NULL
;
1004 if (work
->previous_argument
)
1006 string_delete (work
->previous_argument
);
1007 free ((char*) work
->previous_argument
);
1008 work
->previous_argument
= NULL
;
1011 /* If demangling was successful, ensure that the demangled string is null
1012 terminated and return it. Otherwise, free the demangling decl. */
1016 string_delete (declp
);
1020 string_appendn (declp
, "", 1);
1021 demangled
= declp
-> b
;
1030 demangle_signature -- demangle the signature part of a mangled name
1035 demangle_signature (struct work_stuff *work, const char **mangled,
1040 Consume and demangle the signature portion of the mangled name.
1042 DECLP is the string where demangled output is being built. At
1043 entry it contains the demangled root name from the mangled name
1044 prefix. I.E. either a demangled operator name or the root function
1045 name. In some special cases, it may contain nothing.
1047 *MANGLED points to the current unconsumed location in the mangled
1048 name. As tokens are consumed and demangling is performed, the
1049 pointer is updated to continuously point at the next token to
1052 Demangling GNU style mangled names is nasty because there is no
1053 explicit token that marks the start of the outermost function
1057 demangle_signature (work
, mangled
, declp
)
1058 struct work_stuff
*work
;
1059 const char **mangled
;
1064 int expect_func
= 0;
1065 int expect_return_type
= 0;
1066 const char *oldmangled
= NULL
;
1070 while (success
&& (**mangled
!= '\0'))
1075 oldmangled
= *mangled
;
1076 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1078 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1079 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1085 oldmangled
= *mangled
;
1086 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1087 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1095 /* Static member function */
1096 if (oldmangled
== NULL
)
1098 oldmangled
= *mangled
;
1101 work
-> static_type
= 1;
1107 work
->type_quals
|= code_for_qualifier (**mangled
);
1109 /* a qualified member function */
1110 if (oldmangled
== NULL
)
1111 oldmangled
= *mangled
;
1116 /* Local class name follows after "Lnnn_" */
1119 while (**mangled
&& (**mangled
!= '_'))
1130 case '0': case '1': case '2': case '3': case '4':
1131 case '5': case '6': case '7': case '8': case '9':
1132 if (oldmangled
== NULL
)
1134 oldmangled
= *mangled
;
1136 work
->temp_start
= -1; /* uppermost call to demangle_class */
1137 success
= demangle_class (work
, mangled
, declp
);
1140 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1142 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1144 /* EDG and others will have the "F", so we let the loop cycle
1145 if we are looking at one. */
1146 if (**mangled
!= 'F')
1155 success
= do_type (work
, mangled
, &s
);
1158 string_append (&s
, SCOPE_STRING (work
));
1159 string_prepends (declp
, &s
);
1168 /* ARM/HP style demangling includes a specific 'F' character after
1169 the class name. For GNU style, it is just implied. So we can
1170 safely just consume any 'F' at this point and be compatible
1171 with either style. */
1177 /* For lucid/ARM/HP style we have to forget any types we might
1178 have remembered up to this point, since they were not argument
1179 types. GNU style considers all types seen as available for
1180 back references. See comment in demangle_args() */
1182 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1184 forget_types (work
);
1186 success
= demangle_args (work
, mangled
, declp
);
1187 /* After picking off the function args, we expect to either
1188 find the function return type (preceded by an '_') or the
1189 end of the string. */
1190 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1193 /* At this level, we do not care about the return type. */
1194 success
= do_type (work
, mangled
, &tname
);
1195 string_delete (&tname
);
1202 string_init(&trawname
);
1203 string_init(&tname
);
1204 if (oldmangled
== NULL
)
1206 oldmangled
= *mangled
;
1208 success
= demangle_template (work
, mangled
, &tname
,
1212 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1214 string_append (&tname
, SCOPE_STRING (work
));
1216 string_prepends(declp
, &tname
);
1217 if (work
-> destructor
& 1)
1219 string_prepend (&trawname
, "~");
1220 string_appends (declp
, &trawname
);
1221 work
->destructor
-= 1;
1223 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1225 string_appends (declp
, &trawname
);
1226 work
->constructor
-= 1;
1228 string_delete(&trawname
);
1229 string_delete(&tname
);
1235 if (GNU_DEMANGLING
&& expect_return_type
)
1237 /* Read the return type. */
1239 string_init (&return_type
);
1242 success
= do_type (work
, mangled
, &return_type
);
1243 APPEND_BLANK (&return_type
);
1245 string_prepends (declp
, &return_type
);
1246 string_delete (&return_type
);
1250 /* At the outermost level, we cannot have a return type specified,
1251 so if we run into another '_' at this point we are dealing with
1252 a mangled name that is either bogus, or has been mangled by
1253 some algorithm we don't know how to deal with. So just
1254 reject the entire demangling. */
1255 /* However, "_nnn" is an expected suffix for alternate entry point
1256 numbered nnn for a function, with HP aCC, so skip over that
1257 without reporting failure. pai/1997-09-04 */
1261 while (**mangled
&& isdigit ((unsigned char)**mangled
))
1271 /* A G++ template function. Read the template arguments. */
1272 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1274 if (!(work
->constructor
& 1))
1275 expect_return_type
= 1;
1284 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1286 /* Assume we have stumbled onto the first outermost function
1287 argument token, and start processing args. */
1289 success
= demangle_args (work
, mangled
, declp
);
1293 /* Non-GNU demanglers use a specific token to mark the start
1294 of the outermost function argument tokens. Typically 'F',
1295 for ARM/HP-demangling, for example. So if we find something
1296 we are not prepared for, it must be an error. */
1302 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1305 if (success
&& expect_func
)
1308 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1310 forget_types (work
);
1312 success
= demangle_args (work
, mangled
, declp
);
1313 /* Since template include the mangling of their return types,
1314 we must set expect_func to 0 so that we don't try do
1315 demangle more arguments the next time we get here. */
1320 if (success
&& !func_done
)
1322 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1324 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1325 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1326 first case, and need to ensure that the '(void)' gets added to
1327 the current declp. Note that with ARM/HP, the first case
1328 represents the name of a static data member 'foo::bar',
1329 which is in the current declp, so we leave it alone. */
1330 success
= demangle_args (work
, mangled
, declp
);
1333 if (success
&& PRINT_ARG_TYPES
)
1335 if (work
->static_type
)
1336 string_append (declp
, " static");
1337 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1339 APPEND_BLANK (declp
);
1340 string_append (declp
, qualifier_string (work
->type_quals
));
1350 demangle_method_args (work
, mangled
, declp
)
1351 struct work_stuff
*work
;
1352 const char **mangled
;
1357 if (work
-> static_type
)
1359 string_append (declp
, *mangled
+ 1);
1360 *mangled
+= strlen (*mangled
);
1365 success
= demangle_args (work
, mangled
, declp
);
1373 demangle_template_template_parm (work
, mangled
, tname
)
1374 struct work_stuff
*work
;
1375 const char **mangled
;
1384 string_append (tname
, "template <");
1385 /* get size of template parameter list */
1386 if (get_count (mangled
, &r
))
1388 for (i
= 0; i
< r
; i
++)
1392 string_append (tname
, ", ");
1395 /* Z for type parameters */
1396 if (**mangled
== 'Z')
1399 string_append (tname
, "class");
1401 /* z for template parameters */
1402 else if (**mangled
== 'z')
1406 demangle_template_template_parm (work
, mangled
, tname
);
1414 /* temp is initialized in do_type */
1415 success
= do_type (work
, mangled
, &temp
);
1418 string_appends (tname
, &temp
);
1420 string_delete(&temp
);
1430 if (tname
->p
[-1] == '>')
1431 string_append (tname
, " ");
1432 string_append (tname
, "> class");
1437 demangle_expression (work
, mangled
, s
, tk
)
1438 struct work_stuff
*work
;
1439 const char** mangled
;
1443 int need_operator
= 0;
1447 string_appendn (s
, "(", 1);
1449 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1458 len
= strlen (*mangled
);
1461 i
< sizeof (optable
) / sizeof (optable
[0]);
1464 size_t l
= strlen (optable
[i
].in
);
1467 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1469 string_appendn (s
, " ", 1);
1470 string_append (s
, optable
[i
].out
);
1471 string_appendn (s
, " ", 1);
1484 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1487 if (**mangled
!= 'W')
1491 string_appendn (s
, ")", 1);
1499 demangle_integral_value (work
, mangled
, s
)
1500 struct work_stuff
*work
;
1501 const char** mangled
;
1506 if (**mangled
== 'E')
1507 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1508 else if (**mangled
== 'Q' || **mangled
== 'K')
1509 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1516 /* Negative numbers are indicated with a leading `m'. */
1517 if (**mangled
== 'm')
1519 string_appendn (s
, "-", 1);
1523 /* Read the rest of the number. */
1524 value
= consume_count_with_underscores (mangled
);
1527 char buf
[INTBUF_SIZE
];
1528 sprintf (buf
, "%d", value
);
1529 string_append (s
, buf
);
1531 /* If the next character is an underscore, skip it. */
1532 if (**mangled
== '_')
1543 /* Demangle the real value in MANGLED. */
1546 demangle_real_value (work
, mangled
, s
)
1547 struct work_stuff
*work
;
1548 const char **mangled
;
1551 if (**mangled
== 'E')
1552 return demangle_expression (work
, mangled
, s
, tk_real
);
1554 if (**mangled
== 'm')
1556 string_appendn (s
, "-", 1);
1559 while (isdigit ((unsigned char)**mangled
))
1561 string_appendn (s
, *mangled
, 1);
1564 if (**mangled
== '.') /* fraction */
1566 string_appendn (s
, ".", 1);
1568 while (isdigit ((unsigned char)**mangled
))
1570 string_appendn (s
, *mangled
, 1);
1574 if (**mangled
== 'e') /* exponent */
1576 string_appendn (s
, "e", 1);
1578 while (isdigit ((unsigned char)**mangled
))
1580 string_appendn (s
, *mangled
, 1);
1589 demangle_template_value_parm (work
, mangled
, s
, tk
)
1590 struct work_stuff
*work
;
1591 const char **mangled
;
1597 if (**mangled
== 'Y')
1599 /* The next argument is a template parameter. */
1603 idx
= consume_count_with_underscores (mangled
);
1605 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1606 || consume_count_with_underscores (mangled
) == -1)
1608 if (work
->tmpl_argvec
)
1609 string_append (s
, work
->tmpl_argvec
[idx
]);
1611 string_append_template_idx (s
, idx
);
1613 else if (tk
== tk_integral
)
1614 success
= demangle_integral_value (work
, mangled
, s
);
1615 else if (tk
== tk_char
)
1619 if (**mangled
== 'm')
1621 string_appendn (s
, "-", 1);
1624 string_appendn (s
, "'", 1);
1625 val
= consume_count(mangled
);
1632 string_appendn (s
, &tmp
[0], 1);
1633 string_appendn (s
, "'", 1);
1636 else if (tk
== tk_bool
)
1638 int val
= consume_count (mangled
);
1640 string_appendn (s
, "false", 5);
1642 string_appendn (s
, "true", 4);
1646 else if (tk
== tk_real
)
1647 success
= demangle_real_value (work
, mangled
, s
);
1648 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1650 if (**mangled
== 'Q')
1651 success
= demangle_qualified (work
, mangled
, s
,
1656 int symbol_len
= consume_count (mangled
);
1657 if (symbol_len
== -1)
1659 if (symbol_len
== 0)
1660 string_appendn (s
, "0", 1);
1663 char *p
= xmalloc (symbol_len
+ 1), *q
;
1664 strncpy (p
, *mangled
, symbol_len
);
1665 p
[symbol_len
] = '\0';
1666 /* We use cplus_demangle here, rather than
1667 internal_cplus_demangle, because the name of the entity
1668 mangled here does not make use of any of the squangling
1669 or type-code information we have built up thus far; it is
1670 mangled independently. */
1671 q
= cplus_demangle (p
, work
->options
);
1672 if (tk
== tk_pointer
)
1673 string_appendn (s
, "&", 1);
1674 /* FIXME: Pointer-to-member constants should get a
1675 qualifying class name here. */
1678 string_append (s
, q
);
1682 string_append (s
, p
);
1685 *mangled
+= symbol_len
;
1692 /* Demangle the template name in MANGLED. The full name of the
1693 template (e.g., S<int>) is placed in TNAME. The name without the
1694 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1695 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1696 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1697 the tmeplate is remembered in the list of back-referenceable
1701 demangle_template (work
, mangled
, tname
, trawname
, is_type
, remember
)
1702 struct work_stuff
*work
;
1703 const char **mangled
;
1714 int is_java_array
= 0;
1722 bindex
= register_Btype (work
);
1724 /* get template name */
1725 if (**mangled
== 'z')
1731 idx
= consume_count_with_underscores (mangled
);
1733 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1734 || consume_count_with_underscores (mangled
) == -1)
1737 if (work
->tmpl_argvec
)
1739 string_append (tname
, work
->tmpl_argvec
[idx
]);
1741 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1745 string_append_template_idx (tname
, idx
);
1747 string_append_template_idx (trawname
, idx
);
1752 if ((r
= consume_count (mangled
)) <= 0
1753 || (int) strlen (*mangled
) < r
)
1757 is_java_array
= (work
-> options
& DMGL_JAVA
)
1758 && strncmp (*mangled
, "JArray1Z", 8) == 0;
1759 if (! is_java_array
)
1761 string_appendn (tname
, *mangled
, r
);
1764 string_appendn (trawname
, *mangled
, r
);
1769 string_append (tname
, "<");
1770 /* get size of template parameter list */
1771 if (!get_count (mangled
, &r
))
1777 /* Create an array for saving the template argument values. */
1778 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
1779 work
->ntmpl_args
= r
;
1780 for (i
= 0; i
< r
; i
++)
1781 work
->tmpl_argvec
[i
] = 0;
1783 for (i
= 0; i
< r
; i
++)
1787 string_append (tname
, ", ");
1789 /* Z for type parameters */
1790 if (**mangled
== 'Z')
1793 /* temp is initialized in do_type */
1794 success
= do_type (work
, mangled
, &temp
);
1797 string_appends (tname
, &temp
);
1801 /* Save the template argument. */
1802 int len
= temp
.p
- temp
.b
;
1803 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1804 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
1805 work
->tmpl_argvec
[i
][len
] = '\0';
1808 string_delete(&temp
);
1814 /* z for template parameters */
1815 else if (**mangled
== 'z')
1819 success
= demangle_template_template_parm (work
, mangled
, tname
);
1822 && (r2
= consume_count (mangled
)) > 0
1823 && (int) strlen (*mangled
) >= r2
)
1825 string_append (tname
, " ");
1826 string_appendn (tname
, *mangled
, r2
);
1829 /* Save the template argument. */
1831 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1832 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
1833 work
->tmpl_argvec
[i
][len
] = '\0';
1847 /* otherwise, value parameter */
1849 /* temp is initialized in do_type */
1850 success
= do_type (work
, mangled
, &temp
);
1851 string_delete(&temp
);
1863 success
= demangle_template_value_parm (work
, mangled
, s
,
1864 (type_kind_t
) success
);
1876 int len
= s
->p
- s
->b
;
1877 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1878 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
1879 work
->tmpl_argvec
[i
][len
] = '\0';
1881 string_appends (tname
, s
);
1889 string_append (tname
, "[]");
1893 if (tname
->p
[-1] == '>')
1894 string_append (tname
, " ");
1895 string_append (tname
, ">");
1898 if (is_type
&& remember
)
1899 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
1902 if (work -> static_type)
1904 string_append (declp, *mangled + 1);
1905 *mangled += strlen (*mangled);
1910 success = demangle_args (work, mangled, declp);
1918 arm_pt (work
, mangled
, n
, anchor
, args
)
1919 struct work_stuff
*work
;
1920 const char *mangled
;
1922 const char **anchor
, **args
;
1924 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1925 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1926 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= mystrstr (mangled
, "__pt__")))
1929 *args
= *anchor
+ 6;
1930 len
= consume_count (args
);
1933 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1939 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
1941 if ((*anchor
= mystrstr (mangled
, "__tm__"))
1942 || (*anchor
= mystrstr (mangled
, "__ps__"))
1943 || (*anchor
= mystrstr (mangled
, "__pt__")))
1946 *args
= *anchor
+ 6;
1947 len
= consume_count (args
);
1950 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1956 else if ((*anchor
= mystrstr (mangled
, "__S")))
1959 *args
= *anchor
+ 3;
1960 len
= consume_count (args
);
1963 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1975 demangle_arm_hp_template (work
, mangled
, n
, declp
)
1976 struct work_stuff
*work
;
1977 const char **mangled
;
1983 const char *e
= *mangled
+ n
;
1986 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1988 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
1990 char *start_spec_args
= NULL
;
1992 /* First check for and omit template specialization pseudo-arguments,
1993 such as in "Spec<#1,#1.*>" */
1994 start_spec_args
= strchr (*mangled
, '<');
1995 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
1996 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
1998 string_appendn (declp
, *mangled
, n
);
1999 (*mangled
) += n
+ 1;
2001 if (work
->temp_start
== -1) /* non-recursive call */
2002 work
->temp_start
= declp
->p
- declp
->b
;
2003 string_append (declp
, "<");
2006 string_clear (&arg
);
2010 /* 'T' signals a type parameter */
2012 if (!do_type (work
, mangled
, &arg
))
2013 goto hpacc_template_args_done
;
2018 /* 'U' or 'S' signals an integral value */
2019 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2020 goto hpacc_template_args_done
;
2024 /* 'A' signals a named constant expression (literal) */
2025 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2026 goto hpacc_template_args_done
;
2030 /* Today, 1997-09-03, we have only the above types
2031 of template parameters */
2032 /* FIXME: maybe this should fail and return null */
2033 goto hpacc_template_args_done
;
2035 string_appends (declp
, &arg
);
2036 /* Check if we're at the end of template args.
2037 0 if at end of static member of template class,
2038 _ if done with template args for a function */
2039 if ((**mangled
== '\000') || (**mangled
== '_'))
2042 string_append (declp
, ",");
2044 hpacc_template_args_done
:
2045 string_append (declp
, ">");
2046 string_delete (&arg
);
2047 if (**mangled
== '_')
2051 /* ARM template? (Also handles HP cfront extensions) */
2052 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2057 string_appendn (declp
, *mangled
, p
- *mangled
);
2058 if (work
->temp_start
== -1) /* non-recursive call */
2059 work
->temp_start
= declp
->p
- declp
->b
;
2060 string_append (declp
, "<");
2061 /* should do error checking here */
2063 string_clear (&arg
);
2065 /* Check for type or literal here */
2068 /* HP cfront extensions to ARM for template args */
2069 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2070 /* FIXME: We handle only numeric literals for HP cfront */
2072 /* A typed constant value follows */
2074 if (!do_type (work
, &args
, &type_str
))
2075 goto cfront_template_args_done
;
2076 string_append (&arg
, "(");
2077 string_appends (&arg
, &type_str
);
2078 string_append (&arg
, ")");
2080 goto cfront_template_args_done
;
2082 /* Now snarf a literal value following 'L' */
2083 if (!snarf_numeric_literal (&args
, &arg
))
2084 goto cfront_template_args_done
;
2088 /* Snarf a literal following 'L' */
2090 if (!snarf_numeric_literal (&args
, &arg
))
2091 goto cfront_template_args_done
;
2094 /* Not handling other HP cfront stuff */
2095 if (!do_type (work
, &args
, &arg
))
2096 goto cfront_template_args_done
;
2098 string_appends (declp
, &arg
);
2099 string_append (declp
, ",");
2101 cfront_template_args_done
:
2102 string_delete (&arg
);
2104 --declp
->p
; /* remove extra comma */
2105 string_append (declp
, ">");
2107 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2108 && (*mangled
)[9] == 'N'
2109 && (*mangled
)[8] == (*mangled
)[10]
2110 && strchr (cplus_markers
, (*mangled
)[8]))
2112 /* A member of the anonymous namespace. */
2113 string_append (declp
, "{anonymous}");
2117 if (work
->temp_start
== -1) /* non-recursive call only */
2118 work
->temp_start
= 0; /* disable in recursive calls */
2119 string_appendn (declp
, *mangled
, n
);
2124 /* Extract a class name, possibly a template with arguments, from the
2125 mangled string; qualifiers, local class indicators, etc. have
2126 already been dealt with */
2129 demangle_class_name (work
, mangled
, declp
)
2130 struct work_stuff
*work
;
2131 const char **mangled
;
2137 n
= consume_count (mangled
);
2140 if ((int) strlen (*mangled
) >= n
)
2142 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2153 demangle_class -- demangle a mangled class sequence
2158 demangle_class (struct work_stuff *work, const char **mangled,
2163 DECLP points to the buffer into which demangling is being done.
2165 *MANGLED points to the current token to be demangled. On input,
2166 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2167 On exit, it points to the next token after the mangled class on
2168 success, or the first unconsumed token on failure.
2170 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2171 we are demangling a constructor or destructor. In this case
2172 we prepend "class::class" or "class::~class" to DECLP.
2174 Otherwise, we prepend "class::" to the current DECLP.
2176 Reset the constructor/destructor flags once they have been
2177 "consumed". This allows demangle_class to be called later during
2178 the same demangling, to do normal class demangling.
2180 Returns 1 if demangling is successful, 0 otherwise.
2185 demangle_class (work
, mangled
, declp
)
2186 struct work_stuff
*work
;
2187 const char **mangled
;
2193 char *save_class_name_end
= 0;
2195 string_init (&class_name
);
2196 btype
= register_Btype (work
);
2197 if (demangle_class_name (work
, mangled
, &class_name
))
2199 save_class_name_end
= class_name
.p
;
2200 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2202 /* adjust so we don't include template args */
2203 if (work
->temp_start
&& (work
->temp_start
!= -1))
2205 class_name
.p
= class_name
.b
+ work
->temp_start
;
2207 string_prepends (declp
, &class_name
);
2208 if (work
-> destructor
& 1)
2210 string_prepend (declp
, "~");
2211 work
-> destructor
-= 1;
2215 work
-> constructor
-= 1;
2218 class_name
.p
= save_class_name_end
;
2219 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2220 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2221 string_prepend (declp
, SCOPE_STRING (work
));
2222 string_prepends (declp
, &class_name
);
2225 string_delete (&class_name
);
2233 demangle_prefix -- consume the mangled name prefix and find signature
2238 demangle_prefix (struct work_stuff *work, const char **mangled,
2243 Consume and demangle the prefix of the mangled name.
2245 DECLP points to the string buffer into which demangled output is
2246 placed. On entry, the buffer is empty. On exit it contains
2247 the root function name, the demangled operator name, or in some
2248 special cases either nothing or the completely demangled result.
2250 MANGLED points to the current pointer into the mangled name. As each
2251 token of the mangled name is consumed, it is updated. Upon entry
2252 the current mangled name pointer points to the first character of
2253 the mangled name. Upon exit, it should point to the first character
2254 of the signature if demangling was successful, or to the first
2255 unconsumed character if demangling of the prefix was unsuccessful.
2257 Returns 1 on success, 0 otherwise.
2261 demangle_prefix (work
, mangled
, declp
)
2262 struct work_stuff
*work
;
2263 const char **mangled
;
2270 if (strlen(*mangled
) > 6
2271 && (strncmp(*mangled
, "_imp__", 6) == 0
2272 || strncmp(*mangled
, "__imp_", 6) == 0))
2274 /* it's a symbol imported from a PE dynamic library. Check for both
2275 new style prefix _imp__ and legacy __imp_ used by older versions
2278 work
->dllimported
= 1;
2280 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2282 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2283 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2285 if ((*mangled
)[9] == 'D')
2287 /* it's a GNU global destructor to be executed at program exit */
2289 work
->destructor
= 2;
2290 if (gnu_special (work
, mangled
, declp
))
2293 else if ((*mangled
)[9] == 'I')
2295 /* it's a GNU global constructor to be executed at program init */
2297 work
->constructor
= 2;
2298 if (gnu_special (work
, mangled
, declp
))
2303 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2305 /* it's a ARM global destructor to be executed at program exit */
2307 work
->destructor
= 2;
2309 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2311 /* it's a ARM global constructor to be executed at program initial */
2313 work
->constructor
= 2;
2316 /* This block of code is a reduction in strength time optimization
2318 scan = mystrstr (*mangled, "__"); */
2324 scan
= strchr (scan
, '_');
2325 } while (scan
!= NULL
&& *++scan
!= '_');
2327 if (scan
!= NULL
) --scan
;
2332 /* We found a sequence of two or more '_', ensure that we start at
2333 the last pair in the sequence. */
2334 i
= strspn (scan
, "_");
2345 else if (work
-> static_type
)
2347 if (!isdigit ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2352 else if ((scan
== *mangled
)
2353 && (isdigit ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2354 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2356 /* The ARM says nothing about the mangling of local variables.
2357 But cfront mangles local variables by prepending __<nesting_level>
2358 to them. As an extension to ARM demangling we handle this case. */
2359 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2360 && isdigit ((unsigned char)scan
[2]))
2362 *mangled
= scan
+ 2;
2363 consume_count (mangled
);
2364 string_append (declp
, *mangled
);
2365 *mangled
+= strlen (*mangled
);
2370 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2371 names like __Q2_3foo3bar for nested type names. So don't accept
2372 this style of constructor for cfront demangling. A GNU
2373 style member-template constructor starts with 'H'. */
2374 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2375 work
-> constructor
+= 1;
2376 *mangled
= scan
+ 2;
2379 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2381 /* Cfront-style parameterized type. Handled later as a signature. */
2385 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2387 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2388 || (scan
[2] == 'p' && scan
[3] == 's')
2389 || (scan
[2] == 'p' && scan
[3] == 't')))
2391 /* EDG-style parameterized type. Handled later as a signature. */
2395 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2397 else if ((scan
== *mangled
) && !isdigit ((unsigned char)scan
[2])
2398 && (scan
[2] != 't'))
2400 /* Mangled name starts with "__". Skip over any leading '_' characters,
2401 then find the next "__" that separates the prefix from the signature.
2403 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2404 || (arm_special (mangled
, declp
) == 0))
2406 while (*scan
== '_')
2410 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2412 /* No separator (I.E. "__not_mangled"), or empty signature
2413 (I.E. "__not_mangled_either__") */
2420 /* Look for the LAST occurrence of __, allowing names to
2421 have the '__' sequence embedded in them. */
2422 if (!(ARM_DEMANGLING
|| HP_DEMANGLING
))
2424 while ((tmp
= mystrstr (scan
+ 2, "__")) != NULL
)
2427 if (*(scan
+ 2) == '\0')
2430 demangle_function_name (work
, mangled
, declp
, scan
);
2434 else if (*(scan
+ 2) != '\0')
2436 /* Mangled name does not start with "__" but does have one somewhere
2437 in there with non empty stuff after it. Looks like a global
2439 demangle_function_name (work
, mangled
, declp
, scan
);
2443 /* Doesn't look like a mangled name */
2447 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2449 string_append (declp
, *mangled
);
2450 *mangled
+= strlen (*mangled
);
2460 gnu_special -- special handling of gnu mangled strings
2465 gnu_special (struct work_stuff *work, const char **mangled,
2471 Process some special GNU style mangling forms that don't fit
2472 the normal pattern. For example:
2474 _$_3foo (destructor for class foo)
2475 _vt$foo (foo virtual table)
2476 _vt$foo$bar (foo::bar virtual table)
2477 __vt_foo (foo virtual table, new style with thunks)
2478 _3foo$varname (static data member)
2479 _Q22rs2tu$vw (static data member)
2480 __t6vector1Zii (constructor with template)
2481 __thunk_4__$_7ostream (virtual function thunk)
2485 gnu_special (work
, mangled
, declp
)
2486 struct work_stuff
*work
;
2487 const char **mangled
;
2494 if ((*mangled
)[0] == '_'
2495 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2496 && (*mangled
)[2] == '_')
2498 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2500 work
-> destructor
+= 1;
2502 else if ((*mangled
)[0] == '_'
2503 && (((*mangled
)[1] == '_'
2504 && (*mangled
)[2] == 'v'
2505 && (*mangled
)[3] == 't'
2506 && (*mangled
)[4] == '_')
2507 || ((*mangled
)[1] == 'v'
2508 && (*mangled
)[2] == 't'
2509 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2511 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2512 and create the decl. Note that we consume the entire mangled
2513 input string, which means that demangle_signature has no work
2515 if ((*mangled
)[2] == 'v')
2516 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2518 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2519 while (**mangled
!= '\0')
2525 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2528 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2532 if (isdigit((unsigned char)*mangled
[0]))
2534 n
= consume_count(mangled
);
2535 /* We may be seeing a too-large size, or else a
2536 ".<digits>" indicating a static local symbol. In
2537 any case, declare victory and move on; *don't* try
2538 to use n to allocate. */
2539 if (n
> (int) strlen (*mangled
))
2547 n
= strcspn (*mangled
, cplus_markers
);
2549 string_appendn (declp
, *mangled
, n
);
2553 p
= strpbrk (*mangled
, cplus_markers
);
2554 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2558 string_append (declp
, SCOPE_STRING (work
));
2569 string_append (declp
, " virtual table");
2571 else if ((*mangled
)[0] == '_'
2572 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2573 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2575 /* static data member, "_3foo$varname" for example */
2581 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2584 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2587 n
= consume_count (mangled
);
2588 if (n
< 0 || n
> (long) strlen (*mangled
))
2593 string_appendn (declp
, *mangled
, n
);
2596 if (success
&& (p
== *mangled
))
2598 /* Consumed everything up to the cplus_marker, append the
2601 string_append (declp
, SCOPE_STRING (work
));
2602 n
= strlen (*mangled
);
2603 string_appendn (declp
, *mangled
, n
);
2611 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2616 delta
= consume_count (mangled
);
2621 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2626 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2627 string_append (declp
, buf
);
2628 string_append (declp
, method
);
2630 n
= strlen (*mangled
);
2639 else if (strncmp (*mangled
, "__t", 3) == 0
2640 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2642 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2648 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2651 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2654 success
= demangle_fund_type (work
, mangled
, declp
);
2657 if (success
&& **mangled
!= '\0')
2660 string_append (declp
, p
);
2670 recursively_demangle(work
, mangled
, result
, namelength
)
2671 struct work_stuff
*work
;
2672 const char **mangled
;
2676 char * recurse
= (char *)NULL
;
2677 char * recurse_dem
= (char *)NULL
;
2679 recurse
= (char *) xmalloc (namelength
+ 1);
2680 memcpy (recurse
, *mangled
, namelength
);
2681 recurse
[namelength
] = '\000';
2683 recurse_dem
= cplus_demangle (recurse
, work
->options
);
2687 string_append (result
, recurse_dem
);
2692 string_appendn (result
, *mangled
, namelength
);
2695 *mangled
+= namelength
;
2702 arm_special -- special handling of ARM/lucid mangled strings
2707 arm_special (const char **mangled,
2713 Process some special ARM style mangling forms that don't fit
2714 the normal pattern. For example:
2716 __vtbl__3foo (foo virtual table)
2717 __vtbl__3foo__3bar (bar::foo virtual table)
2722 arm_special (mangled
, declp
)
2723 const char **mangled
;
2730 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
2732 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2733 and create the decl. Note that we consume the entire mangled
2734 input string, which means that demangle_signature has no work
2736 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
2737 while (*scan
!= '\0') /* first check it can be demangled */
2739 n
= consume_count (&scan
);
2742 return (0); /* no good */
2745 if (scan
[0] == '_' && scan
[1] == '_')
2750 (*mangled
) += ARM_VTABLE_STRLEN
;
2751 while (**mangled
!= '\0')
2753 n
= consume_count (mangled
);
2755 || n
> (long) strlen (*mangled
))
2757 string_prependn (declp
, *mangled
, n
);
2759 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
2761 string_prepend (declp
, "::");
2765 string_append (declp
, " virtual table");
2778 demangle_qualified -- demangle 'Q' qualified name strings
2783 demangle_qualified (struct work_stuff *, const char *mangled,
2784 string *result, int isfuncname, int append);
2788 Demangle a qualified name, such as "Q25Outer5Inner" which is
2789 the mangled form of "Outer::Inner". The demangled output is
2790 prepended or appended to the result string according to the
2791 state of the append flag.
2793 If isfuncname is nonzero, then the qualified name we are building
2794 is going to be used as a member function name, so if it is a
2795 constructor or destructor function, append an appropriate
2796 constructor or destructor name. I.E. for the above example,
2797 the result for use as a constructor is "Outer::Inner::Inner"
2798 and the result for use as a destructor is "Outer::Inner::~Inner".
2802 Numeric conversion is ASCII dependent (FIXME).
2807 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
2808 struct work_stuff
*work
;
2809 const char **mangled
;
2819 int bindex
= register_Btype (work
);
2821 /* We only make use of ISFUNCNAME if the entity is a constructor or
2823 isfuncname
= (isfuncname
2824 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
2826 string_init (&temp
);
2827 string_init (&last_name
);
2829 if ((*mangled
)[0] == 'K')
2831 /* Squangling qualified name reuse */
2834 idx
= consume_count_with_underscores (mangled
);
2835 if (idx
== -1 || idx
>= work
-> numk
)
2838 string_append (&temp
, work
-> ktypevec
[idx
]);
2841 switch ((*mangled
)[1])
2844 /* GNU mangled name with more than 9 classes. The count is preceded
2845 by an underscore (to distinguish it from the <= 9 case) and followed
2846 by an underscore. */
2848 qualifiers
= consume_count_with_underscores (mangled
);
2849 if (qualifiers
== -1)
2862 /* The count is in a single digit. */
2863 num
[0] = (*mangled
)[1];
2865 qualifiers
= atoi (num
);
2867 /* If there is an underscore after the digit, skip it. This is
2868 said to be for ARM-qualified names, but the ARM makes no
2869 mention of such an underscore. Perhaps cfront uses one. */
2870 if ((*mangled
)[2] == '_')
2885 /* Pick off the names and collect them in the temp buffer in the order
2886 in which they are found, separated by '::'. */
2888 while (qualifiers
-- > 0)
2891 string_clear (&last_name
);
2893 if (*mangled
[0] == '_')
2896 if (*mangled
[0] == 't')
2898 /* Here we always append to TEMP since we will want to use
2899 the template name without the template parameters as a
2900 constructor or destructor name. The appropriate
2901 (parameter-less) value is returned by demangle_template
2902 in LAST_NAME. We do not remember the template type here,
2903 in order to match the G++ mangling algorithm. */
2904 success
= demangle_template(work
, mangled
, &temp
,
2909 else if (*mangled
[0] == 'K')
2913 idx
= consume_count_with_underscores (mangled
);
2914 if (idx
== -1 || idx
>= work
->numk
)
2917 string_append (&temp
, work
->ktypevec
[idx
]);
2920 if (!success
) break;
2927 /* Now recursively demangle the qualifier
2928 * This is necessary to deal with templates in
2929 * mangling styles like EDG */
2930 namelength
= consume_count (mangled
);
2931 if (namelength
== -1)
2936 recursively_demangle(work
, mangled
, &temp
, namelength
);
2940 success
= do_type (work
, mangled
, &last_name
);
2943 string_appends (&temp
, &last_name
);
2948 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
2951 string_append (&temp
, SCOPE_STRING (work
));
2954 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
2956 /* If we are using the result as a function name, we need to append
2957 the appropriate '::' separated constructor or destructor name.
2958 We do this here because this is the most convenient place, where
2959 we already have a pointer to the name and the length of the name. */
2963 string_append (&temp
, SCOPE_STRING (work
));
2964 if (work
-> destructor
& 1)
2965 string_append (&temp
, "~");
2966 string_appends (&temp
, &last_name
);
2969 /* Now either prepend the temp buffer to the result, or append it,
2970 depending upon the state of the append flag. */
2973 string_appends (result
, &temp
);
2976 if (!STRING_EMPTY (result
))
2977 string_append (&temp
, SCOPE_STRING (work
));
2978 string_prepends (result
, &temp
);
2981 string_delete (&last_name
);
2982 string_delete (&temp
);
2990 get_count -- convert an ascii count to integer, consuming tokens
2995 get_count (const char **type, int *count)
2999 Assume that *type points at a count in a mangled name; set
3000 *count to its value, and set *type to the next character after
3001 the count. There are some weird rules in effect here.
3003 If *type does not point at a string of digits, return zero.
3005 If *type points at a string of digits followed by an
3006 underscore, set *count to their value as an integer, advance
3007 *type to point *after the underscore, and return 1.
3009 If *type points at a string of digits not followed by an
3010 underscore, consume only the first digit. Set *count to its
3011 value as an integer, leave *type pointing after that digit,
3014 The excuse for this odd behavior: in the ARM and HP demangling
3015 styles, a type can be followed by a repeat count of the form
3018 `x' is a single digit specifying how many additional copies
3019 of the type to append to the argument list, and
3021 `y' is one or more digits, specifying the zero-based index of
3022 the first repeated argument in the list. Yes, as you're
3023 unmangling the name you can figure this out yourself, but
3026 So, for example, in `bar__3fooFPiN51', the first argument is a
3027 pointer to an integer (`Pi'), and then the next five arguments
3028 are the same (`N5'), and the first repeat is the function's
3029 second argument (`1').
3033 get_count (type
, count
)
3040 if (!isdigit ((unsigned char)**type
))
3044 *count
= **type
- '0';
3046 if (isdigit ((unsigned char)**type
))
3056 while (isdigit ((unsigned char)*p
));
3067 /* RESULT will be initialised here; it will be freed on failure. The
3068 value returned is really a type_kind_t. */
3071 do_type (work
, mangled
, result
)
3072 struct work_stuff
*work
;
3073 const char **mangled
;
3080 const char *remembered_type
;
3083 type_kind_t tk
= tk_none
;
3085 string_init (&btype
);
3086 string_init (&decl
);
3087 string_init (result
);
3091 while (success
&& !done
)
3097 /* A pointer type */
3101 if (! (work
-> options
& DMGL_JAVA
))
3102 string_prepend (&decl
, "*");
3107 /* A reference type */
3110 string_prepend (&decl
, "&");
3119 if (!STRING_EMPTY (&decl
)
3120 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3122 string_prepend (&decl
, "(");
3123 string_append (&decl
, ")");
3125 string_append (&decl
, "[");
3126 if (**mangled
!= '_')
3127 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3129 if (**mangled
== '_')
3131 string_append (&decl
, "]");
3135 /* A back reference to a previously seen type */
3138 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3144 remembered_type
= work
-> typevec
[n
];
3145 mangled
= &remembered_type
;
3152 if (!STRING_EMPTY (&decl
)
3153 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3155 string_prepend (&decl
, "(");
3156 string_append (&decl
, ")");
3158 /* After picking off the function args, we expect to either find the
3159 function return type (preceded by an '_') or the end of the
3161 if (!demangle_nested_args (work
, mangled
, &decl
)
3162 || (**mangled
!= '_' && **mangled
!= '\0'))
3167 if (success
&& (**mangled
== '_'))
3174 type_quals
= TYPE_UNQUALIFIED
;
3176 member
= **mangled
== 'M';
3179 string_append (&decl
, ")");
3181 /* We don't need to prepend `::' for a qualified name;
3182 demangle_qualified will do that for us. */
3183 if (**mangled
!= 'Q')
3184 string_prepend (&decl
, SCOPE_STRING (work
));
3186 if (isdigit ((unsigned char)**mangled
))
3188 n
= consume_count (mangled
);
3190 || (int) strlen (*mangled
) < n
)
3195 string_prependn (&decl
, *mangled
, n
);
3198 else if (**mangled
== 'X' || **mangled
== 'Y')
3201 do_type (work
, mangled
, &temp
);
3202 string_prepends (&decl
, &temp
);
3204 else if (**mangled
== 't')
3207 string_init (&temp
);
3208 success
= demangle_template (work
, mangled
, &temp
,
3212 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3213 string_clear (&temp
);
3218 else if (**mangled
== 'Q')
3220 success
= demangle_qualified (work
, mangled
, &decl
,
3232 string_prepend (&decl
, "(");
3240 type_quals
|= code_for_qualifier (**mangled
);
3248 if (*(*mangled
)++ != 'F')
3254 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3255 || **mangled
!= '_')
3261 if (! PRINT_ANSI_QUALIFIERS
)
3265 if (type_quals
!= TYPE_UNQUALIFIED
)
3267 APPEND_BLANK (&decl
);
3268 string_append (&decl
, qualifier_string (type_quals
));
3279 if (PRINT_ANSI_QUALIFIERS
)
3281 if (!STRING_EMPTY (&decl
))
3282 string_prepend (&decl
, " ");
3284 string_prepend (&decl
, demangle_qualifier (**mangled
));
3299 if (success
) switch (**mangled
)
3301 /* A qualified name, such as "Outer::Inner". */
3305 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3309 /* A back reference to a previously seen squangled type */
3312 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3315 string_append (result
, work
->btypevec
[n
]);
3320 /* A template parm. We substitute the corresponding argument. */
3325 idx
= consume_count_with_underscores (mangled
);
3328 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3329 || consume_count_with_underscores (mangled
) == -1)
3335 if (work
->tmpl_argvec
)
3336 string_append (result
, work
->tmpl_argvec
[idx
]);
3338 string_append_template_idx (result
, idx
);
3345 success
= demangle_fund_type (work
, mangled
, result
);
3347 tk
= (type_kind_t
) success
;
3353 if (!STRING_EMPTY (&decl
))
3355 string_append (result
, " ");
3356 string_appends (result
, &decl
);
3360 string_delete (result
);
3361 string_delete (&decl
);
3364 /* Assume an integral type, if we're not sure. */
3365 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3370 /* Given a pointer to a type string that represents a fundamental type
3371 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3372 string in which the demangled output is being built in RESULT, and
3373 the WORK structure, decode the types and add them to the result.
3378 "Sl" => "signed long"
3379 "CUs" => "const unsigned short"
3381 The value returned is really a type_kind_t. */
3384 demangle_fund_type (work
, mangled
, result
)
3385 struct work_stuff
*work
;
3386 const char **mangled
;
3394 type_kind_t tk
= tk_integral
;
3396 string_init (&btype
);
3398 /* First pick off any type qualifiers. There can be more than one. */
3407 if (PRINT_ANSI_QUALIFIERS
)
3409 if (!STRING_EMPTY (result
))
3410 string_prepend (result
, " ");
3411 string_prepend (result
, demangle_qualifier (**mangled
));
3417 APPEND_BLANK (result
);
3418 string_append (result
, "unsigned");
3420 case 'S': /* signed char only */
3422 APPEND_BLANK (result
);
3423 string_append (result
, "signed");
3427 APPEND_BLANK (result
);
3428 string_append (result
, "__complex");
3436 /* Now pick off the fundamental type. There can be only one. */
3445 APPEND_BLANK (result
);
3446 string_append (result
, "void");
3450 APPEND_BLANK (result
);
3451 string_append (result
, "long long");
3455 APPEND_BLANK (result
);
3456 string_append (result
, "long");
3460 APPEND_BLANK (result
);
3461 string_append (result
, "int");
3465 APPEND_BLANK (result
);
3466 string_append (result
, "short");
3470 APPEND_BLANK (result
);
3471 string_append (result
, "bool");
3476 APPEND_BLANK (result
);
3477 string_append (result
, "char");
3482 APPEND_BLANK (result
);
3483 string_append (result
, "wchar_t");
3488 APPEND_BLANK (result
);
3489 string_append (result
, "long double");
3494 APPEND_BLANK (result
);
3495 string_append (result
, "double");
3500 APPEND_BLANK (result
);
3501 string_append (result
, "float");
3506 if (!isdigit ((unsigned char)**mangled
))
3513 if (**mangled
== '_')
3518 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3521 if (**mangled
!= '_')
3531 strncpy (buf
, *mangled
, 2);
3533 *mangled
+= min (strlen (*mangled
), 2);
3535 sscanf (buf
, "%x", &dec
);
3536 sprintf (buf
, "int%i_t", dec
);
3537 APPEND_BLANK (result
);
3538 string_append (result
, buf
);
3542 /* An explicit type, such as "6mytype" or "7integer" */
3554 int bindex
= register_Btype (work
);
3556 string_init (&btype
);
3557 if (demangle_class_name (work
, mangled
, &btype
)) {
3558 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3559 APPEND_BLANK (result
);
3560 string_appends (result
, &btype
);
3564 string_delete (&btype
);
3569 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3570 string_appends (result
, &btype
);
3578 return success
? ((int) tk
) : 0;
3582 /* Handle a template's value parameter for HP aCC (extension from ARM)
3583 **mangled points to 'S' or 'U' */
3586 do_hpacc_template_const_value (work
, mangled
, result
)
3587 struct work_stuff
*work ATTRIBUTE_UNUSED
;
3588 const char **mangled
;
3593 if (**mangled
!= 'U' && **mangled
!= 'S')
3596 unsigned_const
= (**mangled
== 'U');
3603 string_append (result
, "-");
3609 /* special case for -2^31 */
3610 string_append (result
, "-2147483648");
3617 /* We have to be looking at an integer now */
3618 if (!(isdigit ((unsigned char)**mangled
)))
3621 /* We only deal with integral values for template
3622 parameters -- so it's OK to look only for digits */
3623 while (isdigit ((unsigned char)**mangled
))
3625 char_str
[0] = **mangled
;
3626 string_append (result
, char_str
);
3631 string_append (result
, "U");
3633 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3634 with L or LL suffixes. pai/1997-09-03 */
3636 return 1; /* success */
3639 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3640 **mangled is pointing to the 'A' */
3643 do_hpacc_template_literal (work
, mangled
, result
)
3644 struct work_stuff
*work
;
3645 const char **mangled
;
3648 int literal_len
= 0;
3652 if (**mangled
!= 'A')
3657 literal_len
= consume_count (mangled
);
3659 if (literal_len
<= 0)
3662 /* Literal parameters are names of arrays, functions, etc. and the
3663 canonical representation uses the address operator */
3664 string_append (result
, "&");
3666 /* Now recursively demangle the literal name */
3667 recurse
= (char *) xmalloc (literal_len
+ 1);
3668 memcpy (recurse
, *mangled
, literal_len
);
3669 recurse
[literal_len
] = '\000';
3671 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3675 string_append (result
, recurse_dem
);
3680 string_appendn (result
, *mangled
, literal_len
);
3682 (*mangled
) += literal_len
;
3689 snarf_numeric_literal (args
, arg
)
3696 string_append (arg
, char_str
);
3699 else if (**args
== '+')
3702 if (!isdigit ((unsigned char)**args
))
3705 while (isdigit ((unsigned char)**args
))
3707 char_str
[0] = **args
;
3708 string_append (arg
, char_str
);
3715 /* Demangle the next argument, given by MANGLED into RESULT, which
3716 *should be an uninitialized* string. It will be initialized here,
3717 and free'd should anything go wrong. */
3720 do_arg (work
, mangled
, result
)
3721 struct work_stuff
*work
;
3722 const char **mangled
;
3725 /* Remember where we started so that we can record the type, for
3726 non-squangling type remembering. */
3727 const char *start
= *mangled
;
3729 string_init (result
);
3731 if (work
->nrepeats
> 0)
3735 if (work
->previous_argument
== 0)
3738 /* We want to reissue the previous type in this argument list. */
3739 string_appends (result
, work
->previous_argument
);
3743 if (**mangled
== 'n')
3745 /* A squangling-style repeat. */
3747 work
->nrepeats
= consume_count(mangled
);
3749 if (work
->nrepeats
<= 0)
3750 /* This was not a repeat count after all. */
3753 if (work
->nrepeats
> 9)
3755 if (**mangled
!= '_')
3756 /* The repeat count should be followed by an '_' in this
3763 /* Now, the repeat is all set up. */
3764 return do_arg (work
, mangled
, result
);
3767 /* Save the result in WORK->previous_argument so that we can find it
3768 if it's repeated. Note that saving START is not good enough: we
3769 do not want to add additional types to the back-referenceable
3770 type vector when processing a repeated type. */
3771 if (work
->previous_argument
)
3772 string_clear (work
->previous_argument
);
3775 work
->previous_argument
= (string
*) xmalloc (sizeof (string
));
3776 string_init (work
->previous_argument
);
3779 if (!do_type (work
, mangled
, work
->previous_argument
))
3782 string_appends (result
, work
->previous_argument
);
3784 remember_type (work
, start
, *mangled
- start
);
3789 remember_type (work
, start
, len
)
3790 struct work_stuff
*work
;
3796 if (work
->forgetting_types
)
3799 if (work
-> ntypes
>= work
-> typevec_size
)
3801 if (work
-> typevec_size
== 0)
3803 work
-> typevec_size
= 3;
3805 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
3809 work
-> typevec_size
*= 2;
3811 = (char **) xrealloc ((char *)work
-> typevec
,
3812 sizeof (char *) * work
-> typevec_size
);
3815 tem
= xmalloc (len
+ 1);
3816 memcpy (tem
, start
, len
);
3818 work
-> typevec
[work
-> ntypes
++] = tem
;
3822 /* Remember a K type class qualifier. */
3824 remember_Ktype (work
, start
, len
)
3825 struct work_stuff
*work
;
3831 if (work
-> numk
>= work
-> ksize
)
3833 if (work
-> ksize
== 0)
3837 = (char **) xmalloc (sizeof (char *) * work
-> ksize
);
3843 = (char **) xrealloc ((char *)work
-> ktypevec
,
3844 sizeof (char *) * work
-> ksize
);
3847 tem
= xmalloc (len
+ 1);
3848 memcpy (tem
, start
, len
);
3850 work
-> ktypevec
[work
-> numk
++] = tem
;
3853 /* Register a B code, and get an index for it. B codes are registered
3854 as they are seen, rather than as they are completed, so map<temp<char> >
3855 registers map<temp<char> > as B0, and temp<char> as B1 */
3858 register_Btype (work
)
3859 struct work_stuff
*work
;
3863 if (work
-> numb
>= work
-> bsize
)
3865 if (work
-> bsize
== 0)
3869 = (char **) xmalloc (sizeof (char *) * work
-> bsize
);
3875 = (char **) xrealloc ((char *)work
-> btypevec
,
3876 sizeof (char *) * work
-> bsize
);
3879 ret
= work
-> numb
++;
3880 work
-> btypevec
[ret
] = NULL
;
3884 /* Store a value into a previously registered B code type. */
3887 remember_Btype (work
, start
, len
, index
)
3888 struct work_stuff
*work
;
3894 tem
= xmalloc (len
+ 1);
3895 memcpy (tem
, start
, len
);
3897 work
-> btypevec
[index
] = tem
;
3900 /* Lose all the info related to B and K type codes. */
3902 forget_B_and_K_types (work
)
3903 struct work_stuff
*work
;
3907 while (work
-> numk
> 0)
3909 i
= --(work
-> numk
);
3910 if (work
-> ktypevec
[i
] != NULL
)
3912 free (work
-> ktypevec
[i
]);
3913 work
-> ktypevec
[i
] = NULL
;
3917 while (work
-> numb
> 0)
3919 i
= --(work
-> numb
);
3920 if (work
-> btypevec
[i
] != NULL
)
3922 free (work
-> btypevec
[i
]);
3923 work
-> btypevec
[i
] = NULL
;
3927 /* Forget the remembered types, but not the type vector itself. */
3931 struct work_stuff
*work
;
3935 while (work
-> ntypes
> 0)
3937 i
= --(work
-> ntypes
);
3938 if (work
-> typevec
[i
] != NULL
)
3940 free (work
-> typevec
[i
]);
3941 work
-> typevec
[i
] = NULL
;
3946 /* Process the argument list part of the signature, after any class spec
3947 has been consumed, as well as the first 'F' character (if any). For
3950 "__als__3fooRT0" => process "RT0"
3951 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3953 DECLP must be already initialised, usually non-empty. It won't be freed
3956 Note that g++ differs significantly from ARM and lucid style mangling
3957 with regards to references to previously seen types. For example, given
3958 the source fragment:
3962 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3965 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3966 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3968 g++ produces the names:
3973 while lcc (and presumably other ARM style compilers as well) produces:
3975 foo__FiR3fooT1T2T1T2
3976 __ct__3fooFiR3fooT1T2T1T2
3978 Note that g++ bases its type numbers starting at zero and counts all
3979 previously seen types, while lucid/ARM bases its type numbers starting
3980 at one and only considers types after it has seen the 'F' character
3981 indicating the start of the function args. For lucid/ARM style, we
3982 account for this difference by discarding any previously seen types when
3983 we see the 'F' character, and subtracting one from the type number
3989 demangle_args (work
, mangled
, declp
)
3990 struct work_stuff
*work
;
3991 const char **mangled
;
4001 if (PRINT_ARG_TYPES
)
4003 string_append (declp
, "(");
4004 if (**mangled
== '\0')
4006 string_append (declp
, "void");
4010 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4011 || work
->nrepeats
> 0)
4013 if ((**mangled
== 'N') || (**mangled
== 'T'))
4015 temptype
= *(*mangled
)++;
4017 if (temptype
== 'N')
4019 if (!get_count (mangled
, &r
))
4028 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4030 /* If we have 10 or more types we might have more than a 1 digit
4031 index so we'll have to consume the whole count here. This
4032 will lose if the next thing is a type name preceded by a
4033 count but it's impossible to demangle that case properly
4034 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4035 Pc, ...)" or "(..., type12, char *, ...)" */
4036 if ((t
= consume_count(mangled
)) <= 0)
4043 if (!get_count (mangled
, &t
))
4048 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4052 /* Validate the type index. Protect against illegal indices from
4053 malformed type strings. */
4054 if ((t
< 0) || (t
>= work
-> ntypes
))
4058 while (work
->nrepeats
> 0 || --r
>= 0)
4060 tem
= work
-> typevec
[t
];
4061 if (need_comma
&& PRINT_ARG_TYPES
)
4063 string_append (declp
, ", ");
4065 if (!do_arg (work
, &tem
, &arg
))
4069 if (PRINT_ARG_TYPES
)
4071 string_appends (declp
, &arg
);
4073 string_delete (&arg
);
4079 if (need_comma
&& PRINT_ARG_TYPES
)
4080 string_append (declp
, ", ");
4081 if (!do_arg (work
, mangled
, &arg
))
4083 if (PRINT_ARG_TYPES
)
4084 string_appends (declp
, &arg
);
4085 string_delete (&arg
);
4090 if (**mangled
== 'e')
4093 if (PRINT_ARG_TYPES
)
4097 string_append (declp
, ",");
4099 string_append (declp
, "...");
4103 if (PRINT_ARG_TYPES
)
4105 string_append (declp
, ")");
4110 /* Like demangle_args, but for demangling the argument lists of function
4111 and method pointers or references, not top-level declarations. */
4114 demangle_nested_args (work
, mangled
, declp
)
4115 struct work_stuff
*work
;
4116 const char **mangled
;
4119 string
* saved_previous_argument
;
4123 /* The G++ name-mangling algorithm does not remember types on nested
4124 argument lists, unless -fsquangling is used, and in that case the
4125 type vector updated by remember_type is not used. So, we turn
4126 off remembering of types here. */
4127 ++work
->forgetting_types
;
4129 /* For the repeat codes used with -fsquangling, we must keep track of
4130 the last argument. */
4131 saved_previous_argument
= work
->previous_argument
;
4132 saved_nrepeats
= work
->nrepeats
;
4133 work
->previous_argument
= 0;
4136 /* Actually demangle the arguments. */
4137 result
= demangle_args (work
, mangled
, declp
);
4139 /* Restore the previous_argument field. */
4140 if (work
->previous_argument
)
4141 string_delete (work
->previous_argument
);
4142 work
->previous_argument
= saved_previous_argument
;
4143 --work
->forgetting_types
;
4144 work
->nrepeats
= saved_nrepeats
;
4150 demangle_function_name (work
, mangled
, declp
, scan
)
4151 struct work_stuff
*work
;
4152 const char **mangled
;
4160 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4161 string_need (declp
, 1);
4162 *(declp
-> p
) = '\0';
4164 /* Consume the function name, including the "__" separating the name
4165 from the signature. We are guaranteed that SCAN points to the
4168 (*mangled
) = scan
+ 2;
4169 /* We may be looking at an instantiation of a template function:
4170 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4171 following _F marks the start of the function arguments. Handle
4172 the template arguments first. */
4174 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4176 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4177 /* This leaves MANGLED pointing to the 'F' marking func args */
4180 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4183 /* See if we have an ARM style constructor or destructor operator.
4184 If so, then just record it, clear the decl, and return.
4185 We can't build the actual constructor/destructor decl until later,
4186 when we recover the class name from the signature. */
4188 if (strcmp (declp
-> b
, "__ct") == 0)
4190 work
-> constructor
+= 1;
4191 string_clear (declp
);
4194 else if (strcmp (declp
-> b
, "__dt") == 0)
4196 work
-> destructor
+= 1;
4197 string_clear (declp
);
4202 if (declp
->p
- declp
->b
>= 3
4203 && declp
->b
[0] == 'o'
4204 && declp
->b
[1] == 'p'
4205 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4207 /* see if it's an assignment expression */
4208 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4209 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4211 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4213 int len
= declp
->p
- declp
->b
- 10;
4214 if ((int) strlen (optable
[i
].in
) == len
4215 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4217 string_clear (declp
);
4218 string_append (declp
, "operator");
4219 string_append (declp
, optable
[i
].out
);
4220 string_append (declp
, "=");
4227 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4229 int len
= declp
->p
- declp
->b
- 3;
4230 if ((int) strlen (optable
[i
].in
) == len
4231 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4233 string_clear (declp
);
4234 string_append (declp
, "operator");
4235 string_append (declp
, optable
[i
].out
);
4241 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4242 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4244 /* type conversion operator */
4246 if (do_type (work
, &tem
, &type
))
4248 string_clear (declp
);
4249 string_append (declp
, "operator ");
4250 string_appends (declp
, &type
);
4251 string_delete (&type
);
4254 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4255 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4258 /* type conversion operator. */
4260 if (do_type (work
, &tem
, &type
))
4262 string_clear (declp
);
4263 string_append (declp
, "operator ");
4264 string_appends (declp
, &type
);
4265 string_delete (&type
);
4268 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4269 && islower(declp
->b
[2])
4270 && islower(declp
->b
[3]))
4272 if (declp
->b
[4] == '\0')
4275 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4277 if (strlen (optable
[i
].in
) == 2
4278 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4280 string_clear (declp
);
4281 string_append (declp
, "operator");
4282 string_append (declp
, optable
[i
].out
);
4289 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4292 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4294 if (strlen (optable
[i
].in
) == 3
4295 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4297 string_clear (declp
);
4298 string_append (declp
, "operator");
4299 string_append (declp
, optable
[i
].out
);
4308 /* a mini string-handling package */
4323 s
->p
= s
->b
= xmalloc (n
);
4326 else if (s
->e
- s
->p
< n
)
4331 s
->b
= xrealloc (s
->b
, n
);
4344 s
->b
= s
->e
= s
->p
= NULL
;
4352 s
->b
= s
->p
= s
->e
= NULL
;
4368 return (s
->b
== s
->p
);
4374 string_append (p
, s
)
4379 if (s
== NULL
|| *s
== '\0')
4383 memcpy (p
->p
, s
, n
);
4388 string_appends (p
, s
)
4397 memcpy (p
->p
, s
->b
, n
);
4403 string_appendn (p
, s
, n
)
4411 memcpy (p
->p
, s
, n
);
4417 string_prepend (p
, s
)
4421 if (s
!= NULL
&& *s
!= '\0')
4423 string_prependn (p
, s
, strlen (s
));
4428 string_prepends (p
, s
)
4433 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4438 string_prependn (p
, s
, n
)
4448 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4452 memcpy (p
->b
, s
, n
);
4458 string_append_template_idx (s
, idx
)
4462 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4463 sprintf(buf
, "T%d", idx
);
4464 string_append (s
, buf
);
4467 /* To generate a standalone demangler program for testing purposes,
4468 just compile and link this file with -DMAIN and libiberty.a. When
4469 run, it demangles each command line arg, or each stdin string, and
4470 prints the result on stdout. */
4476 static const char *program_name
;
4477 static const char *program_version
= VERSION
;
4478 static int flags
= DMGL_PARAMS
| DMGL_ANSI
;
4480 static void demangle_it
PARAMS ((char *));
4481 static void usage
PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN
;
4482 static void fatal
PARAMS ((const char *)) ATTRIBUTE_NORETURN
;
4485 demangle_it (mangled_name
)
4490 result
= cplus_demangle (mangled_name
, flags
);
4493 printf ("%s\n", mangled_name
);
4497 printf ("%s\n", result
);
4503 print_demangler_list (stream
)
4506 struct demangler_engine
*demangler
;
4508 fprintf (stream
, "{%s", libiberty_demanglers
->demangling_style_name
);
4510 for (demangler
= libiberty_demanglers
+ 1;
4511 demangler
->demangling_style
!= unknown_demangling
;
4513 fprintf (stream
, ",%s", demangler
->demangling_style_name
);
4515 fprintf (stream
, "}");
4519 usage (stream
, status
)
4524 Usage: %s [-_] [-n] [--strip-underscores] [--no-strip-underscores] \n",
4529 print_demangler_list (stream
);
4530 fprintf (stream
, "]\n");
4534 print_demangler_list (stream
);
4535 fprintf (stream
, "]\n");
4538 [--help] [--version] [arg...]\n");
4542 #define MBUF_SIZE 32767
4543 char mbuffer
[MBUF_SIZE
];
4545 /* Defined in the automatically-generated underscore.c. */
4546 extern int prepends_underscore
;
4548 int strip_underscore
= 0;
4550 static struct option long_options
[] = {
4551 {"strip-underscores", no_argument
, 0, '_'},
4552 {"format", required_argument
, 0, 's'},
4553 {"help", no_argument
, 0, 'h'},
4554 {"java", no_argument
, 0, 'j'},
4555 {"no-strip-underscores", no_argument
, 0, 'n'},
4556 {"version", no_argument
, 0, 'v'},
4557 {0, no_argument
, 0, 0}
4560 /* More 'friendly' abort that prints the line and file.
4561 config.h can #define abort fancy_abort if you like that sort of thing. */
4566 fatal ("Internal gcc abort.");
4571 standard_symbol_characters
PARAMS ((void));
4574 hp_symbol_characters
PARAMS ((void));
4576 /* Return the string of non-alnum characters that may occur
4577 as a valid symbol component, in the standard assembler symbol
4581 standard_symbol_characters ()
4587 /* Return the string of non-alnum characters that may occur
4588 as a valid symbol name component in an HP object file.
4590 Note that, since HP's compiler generates object code straight from
4591 C++ source, without going through an assembler, its mangled
4592 identifiers can use all sorts of characters that no assembler would
4593 tolerate, so the alphabet this function creates is a little odd.
4594 Here are some sample mangled identifiers offered by HP:
4596 typeid*__XT24AddressIndExpClassMember_
4597 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4598 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4600 This still seems really weird to me, since nowhere else in this
4601 file is there anything to recognize curly brackets, parens, etc.
4602 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4603 this is right, but I still strongly suspect that there's a
4604 misunderstanding here.
4606 If we decide it's better for c++filt to use HP's assembler syntax
4607 to scrape identifiers out of its input, here's the definition of
4608 the symbol name syntax from the HP assembler manual:
4610 Symbols are composed of uppercase and lowercase letters, decimal
4611 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4612 underscore (_). A symbol can begin with a letter, digit underscore or
4613 dollar sign. If a symbol begins with a digit, it must contain a
4614 non-digit character.
4618 hp_symbol_characters ()
4620 return "_$.<>#,*&[]:(){}";
4624 extern int main
PARAMS ((int, char **));
4633 const char *valid_symbols
;
4635 program_name
= argv
[0];
4637 strip_underscore
= prepends_underscore
;
4639 while ((c
= getopt_long (argc
, argv
, "_ns:j", long_options
, (int *) 0)) != EOF
)
4649 strip_underscore
= 0;
4652 printf ("GNU %s (C++ demangler), version %s\n", program_name
, program_version
);
4655 strip_underscore
= 1;
4662 enum demangling_styles style
;
4664 style
= cplus_demangle_name_to_style (optarg
);
4665 if (style
== unknown_demangling
)
4667 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
4668 program_name
, optarg
);
4672 cplus_demangle_set_style (style
);
4680 for ( ; optind
< argc
; optind
++)
4682 demangle_it (argv
[optind
]);
4687 switch (current_demangling_style
)
4689 case gnu_demangling
:
4690 case lucid_demangling
:
4691 case arm_demangling
:
4692 case edg_demangling
:
4693 valid_symbols
= standard_symbol_characters ();
4696 valid_symbols
= hp_symbol_characters ();
4699 /* Folks should explicitly indicate the appropriate alphabet for
4700 each demangling. Providing a default would allow the
4701 question to go unconsidered. */
4709 /* Try to read a label. */
4710 while (c
!= EOF
&& (isalnum (c
) || strchr (valid_symbols
, c
)))
4712 if (i
>= MBUF_SIZE
-1)
4721 if (mbuffer
[0] == '.')
4723 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
4731 result
= cplus_demangle (mbuffer
+ skip_first
, flags
);
4734 if (mbuffer
[0] == '.')
4736 fputs (result
, stdout
);
4740 fputs (mbuffer
, stdout
);
4757 fprintf (stderr
, "%s: %s\n", program_name
, str
);
4765 register PTR value
= (PTR
) malloc (size
);
4767 fatal ("virtual memory exhausted");
4772 xrealloc (ptr
, size
)
4776 register PTR value
= (PTR
) realloc (ptr
, size
);
4778 fatal ("virtual memory exhausted");