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 extern void fancy_abort
PARAMS ((void)) ATTRIBUTE_NORETURN
;
58 static const char *mystrstr
PARAMS ((const char *, const char *));
64 register const char *p
= s1
;
65 register int len
= strlen (s2
);
67 for (; (p
= strchr (p
, *s2
)) != 0; p
++)
69 if (strncmp (p
, s2
, len
) == 0)
77 /* In order to allow a single demangler executable to demangle strings
78 using various common values of CPLUS_MARKER, as well as any specific
79 one set at compile time, we maintain a string containing all the
80 commonly used ones, and check to see if the marker we are looking for
81 is in that string. CPLUS_MARKER is usually '$' on systems where the
82 assembler can deal with that. Where the assembler can't, it's usually
83 '.' (but on many systems '.' is used for other things). We put the
84 current defined CPLUS_MARKER first (which defaults to '$'), followed
85 by the next most common value, followed by an explicit '$' in case
86 the value of CPLUS_MARKER is not '$'.
88 We could avoid this if we could just get g++ to tell us what the actual
89 cplus marker character is as part of the debug information, perhaps by
90 ensuring that it is the character that terminates the gcc<n>_compiled
91 marker symbol (FIXME). */
93 #if !defined (CPLUS_MARKER)
94 #define CPLUS_MARKER '$'
97 enum demangling_styles current_demangling_style
= gnu_demangling
;
99 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
101 static char char_str
[2] = { '\000', '\000' };
104 set_cplus_marker_for_demangling (ch
)
107 cplus_markers
[0] = ch
;
110 typedef struct string
/* Beware: these aren't required to be */
111 { /* '\0' terminated. */
112 char *b
; /* pointer to start of string */
113 char *p
; /* pointer after last character */
114 char *e
; /* pointer after end of allocated space */
117 /* Stuff that is shared between sub-routines.
118 Using a shared structure allows cplus_demangle to be reentrant. */
134 int static_type
; /* A static member function */
135 int temp_start
; /* index in demangled to start of template args */
136 int type_quals
; /* The type qualifiers. */
137 int dllimported
; /* Symbol imported from a PE DLL */
138 char **tmpl_argvec
; /* Template function arguments. */
139 int ntmpl_args
; /* The number of template function arguments. */
140 int forgetting_types
; /* Nonzero if we are not remembering the types
142 string
* previous_argument
; /* The last function argument demangled. */
143 int nrepeats
; /* The number of times to repeat the previous
147 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
148 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
150 static const struct optable
156 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
157 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
158 {"new", " new", 0}, /* old (1.91, and 1.x) */
159 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
160 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
161 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
162 {"as", "=", DMGL_ANSI
}, /* ansi */
163 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
164 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
165 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
166 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
167 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
168 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
169 {"plus", "+", 0}, /* old */
170 {"pl", "+", DMGL_ANSI
}, /* ansi */
171 {"apl", "+=", DMGL_ANSI
}, /* ansi */
172 {"minus", "-", 0}, /* old */
173 {"mi", "-", DMGL_ANSI
}, /* ansi */
174 {"ami", "-=", DMGL_ANSI
}, /* ansi */
175 {"mult", "*", 0}, /* old */
176 {"ml", "*", DMGL_ANSI
}, /* ansi */
177 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
178 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
179 {"convert", "+", 0}, /* old (unary +) */
180 {"negate", "-", 0}, /* old (unary -) */
181 {"trunc_mod", "%", 0}, /* old */
182 {"md", "%", DMGL_ANSI
}, /* ansi */
183 {"amd", "%=", DMGL_ANSI
}, /* ansi */
184 {"trunc_div", "/", 0}, /* old */
185 {"dv", "/", DMGL_ANSI
}, /* ansi */
186 {"adv", "/=", DMGL_ANSI
}, /* ansi */
187 {"truth_andif", "&&", 0}, /* old */
188 {"aa", "&&", DMGL_ANSI
}, /* ansi */
189 {"truth_orif", "||", 0}, /* old */
190 {"oo", "||", DMGL_ANSI
}, /* ansi */
191 {"truth_not", "!", 0}, /* old */
192 {"nt", "!", DMGL_ANSI
}, /* ansi */
193 {"postincrement","++", 0}, /* old */
194 {"pp", "++", DMGL_ANSI
}, /* ansi */
195 {"postdecrement","--", 0}, /* old */
196 {"mm", "--", DMGL_ANSI
}, /* ansi */
197 {"bit_ior", "|", 0}, /* old */
198 {"or", "|", DMGL_ANSI
}, /* ansi */
199 {"aor", "|=", DMGL_ANSI
}, /* ansi */
200 {"bit_xor", "^", 0}, /* old */
201 {"er", "^", DMGL_ANSI
}, /* ansi */
202 {"aer", "^=", DMGL_ANSI
}, /* ansi */
203 {"bit_and", "&", 0}, /* old */
204 {"ad", "&", DMGL_ANSI
}, /* ansi */
205 {"aad", "&=", DMGL_ANSI
}, /* ansi */
206 {"bit_not", "~", 0}, /* old */
207 {"co", "~", DMGL_ANSI
}, /* ansi */
208 {"call", "()", 0}, /* old */
209 {"cl", "()", DMGL_ANSI
}, /* ansi */
210 {"alshift", "<<", 0}, /* old */
211 {"ls", "<<", DMGL_ANSI
}, /* ansi */
212 {"als", "<<=", DMGL_ANSI
}, /* ansi */
213 {"arshift", ">>", 0}, /* old */
214 {"rs", ">>", DMGL_ANSI
}, /* ansi */
215 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
216 {"component", "->", 0}, /* old */
217 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
218 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
219 {"indirect", "*", 0}, /* old */
220 {"method_call", "->()", 0}, /* old */
221 {"addr", "&", 0}, /* old (unary &) */
222 {"array", "[]", 0}, /* old */
223 {"vc", "[]", DMGL_ANSI
}, /* ansi */
224 {"compound", ", ", 0}, /* old */
225 {"cm", ", ", DMGL_ANSI
}, /* ansi */
226 {"cond", "?:", 0}, /* old */
227 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
228 {"max", ">?", 0}, /* old */
229 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
230 {"min", "<?", 0}, /* old */
231 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
232 {"nop", "", 0}, /* old (for operator=) */
233 {"rm", "->*", DMGL_ANSI
}, /* ansi */
234 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
237 /* These values are used to indicate the various type varieties.
238 They are all non-zero so that they can be used as `success'
240 typedef enum type_kind_t
251 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
252 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
253 string_prepend(str, " ");}
254 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
255 string_append(str, " ");}
256 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
258 /* The scope separator appropriate for the language being demangled. */
260 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
262 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
263 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
265 /* Prototypes for local functions */
268 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
271 squangle_mop_up
PARAMS ((struct work_stuff
*));
275 demangle_method_args
PARAMS ((struct work_stuff
*, const char **, string
*));
279 internal_cplus_demangle
PARAMS ((struct work_stuff
*, const char *));
282 demangle_template_template_parm
PARAMS ((struct work_stuff
*work
,
283 const char **, string
*));
286 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*,
287 string
*, int, int));
290 arm_pt
PARAMS ((struct work_stuff
*, const char *, int, const char **,
294 demangle_class_name
PARAMS ((struct work_stuff
*, const char **, string
*));
297 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
301 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
304 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
307 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
310 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
313 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
316 arm_special
PARAMS ((const char **, string
*));
319 string_need
PARAMS ((string
*, int));
322 string_delete
PARAMS ((string
*));
325 string_init
PARAMS ((string
*));
328 string_clear
PARAMS ((string
*));
332 string_empty
PARAMS ((string
*));
336 string_append
PARAMS ((string
*, const char *));
339 string_appends
PARAMS ((string
*, string
*));
342 string_appendn
PARAMS ((string
*, const char *, int));
345 string_prepend
PARAMS ((string
*, const char *));
348 string_prependn
PARAMS ((string
*, const char *, int));
351 get_count
PARAMS ((const char **, int *));
354 consume_count
PARAMS ((const char **));
357 consume_count_with_underscores
PARAMS ((const char**));
360 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
363 demangle_nested_args
PARAMS ((struct work_stuff
*, const char**, string
*));
366 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
369 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
372 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
376 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
379 remember_Btype
PARAMS ((struct work_stuff
*, const char *, int, int));
382 register_Btype
PARAMS ((struct work_stuff
*));
385 remember_Ktype
PARAMS ((struct work_stuff
*, const char *, int));
388 forget_types
PARAMS ((struct work_stuff
*));
391 forget_B_and_K_types
PARAMS ((struct work_stuff
*));
394 string_prepends
PARAMS ((string
*, string
*));
397 demangle_template_value_parm
PARAMS ((struct work_stuff
*, const char**,
398 string
*, type_kind_t
));
401 do_hpacc_template_const_value
PARAMS ((struct work_stuff
*, const char **, string
*));
404 do_hpacc_template_literal
PARAMS ((struct work_stuff
*, const char **, string
*));
407 snarf_numeric_literal
PARAMS ((const char **, string
*));
409 /* There is a TYPE_QUAL value for each type qualifier. They can be
410 combined by bitwise-or to form the complete set of qualifiers for a
413 #define TYPE_UNQUALIFIED 0x0
414 #define TYPE_QUAL_CONST 0x1
415 #define TYPE_QUAL_VOLATILE 0x2
416 #define TYPE_QUAL_RESTRICT 0x4
419 code_for_qualifier
PARAMS ((int));
422 qualifier_string
PARAMS ((int));
425 demangle_qualifier
PARAMS ((int));
428 demangle_integral_value
PARAMS ((struct work_stuff
*, const char **,
432 demangle_arm_hp_template
PARAMS ((struct work_stuff
*, const char **, int,
436 recursively_demangle
PARAMS ((struct work_stuff
*, const char **, string
*,
440 standard_symbol_characters
PARAMS ((void));
443 hp_symbol_characters
PARAMS ((void));
445 /* Translate count to integer, consuming tokens in the process.
446 Conversion terminates on the first non-digit character.
448 Trying to consume something that isn't a count results in no
449 consumption of input and a return of -1.
451 Overflow consumes the rest of the digits, and returns -1. */
459 if (! isdigit ((unsigned char)**type
))
462 while (isdigit ((unsigned char)**type
))
466 /* Check for overflow.
467 We assume that count is represented using two's-complement;
468 no power of two is divisible by ten, so if an overflow occurs
469 when multiplying by ten, the result will not be a multiple of
471 if ((count
% 10) != 0)
473 while (isdigit ((unsigned char) **type
))
478 count
+= **type
- '0';
486 /* Like consume_count, but for counts that are preceded and followed
487 by '_' if they are greater than 10. Also, -1 is returned for
488 failure, since 0 can be a valid value. */
491 consume_count_with_underscores (mangled
)
492 const char **mangled
;
496 if (**mangled
== '_')
499 if (!isdigit ((unsigned char)**mangled
))
502 idx
= consume_count (mangled
);
503 if (**mangled
!= '_')
504 /* The trailing underscore was missing. */
511 if (**mangled
< '0' || **mangled
> '9')
514 idx
= **mangled
- '0';
521 /* C is the code for a type-qualifier. Return the TYPE_QUAL
522 corresponding to this qualifier. */
525 code_for_qualifier (c
)
531 return TYPE_QUAL_CONST
;
534 return TYPE_QUAL_VOLATILE
;
537 return TYPE_QUAL_RESTRICT
;
543 /* C was an invalid qualifier. */
547 /* Return the string corresponding to the qualifiers given by
551 qualifier_string (type_quals
)
556 case TYPE_UNQUALIFIED
:
559 case TYPE_QUAL_CONST
:
562 case TYPE_QUAL_VOLATILE
:
565 case TYPE_QUAL_RESTRICT
:
568 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
569 return "const volatile";
571 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
572 return "const __restrict";
574 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
575 return "volatile __restrict";
577 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
578 return "const volatile __restrict";
584 /* TYPE_QUALS was an invalid qualifier set. */
588 /* C is the code for a type-qualifier. Return the string
589 corresponding to this qualifier. This function should only be
590 called with a valid qualifier code. */
593 demangle_qualifier (c
)
596 return qualifier_string (code_for_qualifier (c
));
600 cplus_demangle_opname (opname
, result
, options
)
607 struct work_stuff work
[1];
610 len
= strlen(opname
);
613 memset ((char *) work
, 0, sizeof (work
));
614 work
->options
= options
;
616 if (opname
[0] == '_' && opname
[1] == '_'
617 && opname
[2] == 'o' && opname
[3] == 'p')
620 /* type conversion operator. */
622 if (do_type (work
, &tem
, &type
))
624 strcat (result
, "operator ");
625 strncat (result
, type
.b
, type
.p
- type
.b
);
626 string_delete (&type
);
630 else if (opname
[0] == '_' && opname
[1] == '_'
631 && opname
[2] >= 'a' && opname
[2] <= 'z'
632 && opname
[3] >= 'a' && opname
[3] <= 'z')
634 if (opname
[4] == '\0')
638 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
640 if (strlen (optable
[i
].in
) == 2
641 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
643 strcat (result
, "operator");
644 strcat (result
, optable
[i
].out
);
652 if (opname
[2] == 'a' && opname
[5] == '\0')
656 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
658 if (strlen (optable
[i
].in
) == 3
659 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
661 strcat (result
, "operator");
662 strcat (result
, optable
[i
].out
);
673 && strchr (cplus_markers
, opname
[2]) != NULL
)
675 /* see if it's an assignment expression */
676 if (len
>= 10 /* op$assign_ */
677 && memcmp (opname
+ 3, "assign_", 7) == 0)
680 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
683 if ((int) strlen (optable
[i
].in
) == len1
684 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
686 strcat (result
, "operator");
687 strcat (result
, optable
[i
].out
);
688 strcat (result
, "=");
697 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
700 if ((int) strlen (optable
[i
].in
) == len1
701 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
703 strcat (result
, "operator");
704 strcat (result
, optable
[i
].out
);
711 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
712 && strchr (cplus_markers
, opname
[4]) != NULL
)
714 /* type conversion operator */
716 if (do_type (work
, &tem
, &type
))
718 strcat (result
, "operator ");
719 strncat (result
, type
.b
, type
.p
- type
.b
);
720 string_delete (&type
);
724 squangle_mop_up (work
);
728 /* Takes operator name as e.g. "++" and returns mangled
729 operator name (e.g. "postincrement_expr"), or NULL if not found.
731 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
732 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
735 cplus_mangle_opname (opname
, options
)
742 len
= strlen (opname
);
743 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
745 if ((int) strlen (optable
[i
].out
) == len
746 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
747 && memcmp (optable
[i
].out
, opname
, len
) == 0)
748 return optable
[i
].in
;
753 /* char *cplus_demangle (const char *mangled, int options)
755 If MANGLED is a mangled function name produced by GNU C++, then
756 a pointer to a malloced string giving a C++ representation
757 of the name will be returned; otherwise NULL will be returned.
758 It is the caller's responsibility to free the string which
761 The OPTIONS arg may contain one or more of the following bits:
763 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
765 DMGL_PARAMS Function parameters are included.
769 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
770 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
771 cplus_demangle ("foo__1Ai", 0) => "A::foo"
773 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
774 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
775 cplus_demangle ("foo__1Afe", 0) => "A::foo"
777 Note that any leading underscores, or other such characters prepended by
778 the compilation system, are presumed to have already been stripped from
782 cplus_demangle (mangled
, options
)
787 struct work_stuff work
[1];
788 memset ((char *) work
, 0, sizeof (work
));
789 work
-> options
= options
;
790 if ((work
-> options
& DMGL_STYLE_MASK
) == 0)
791 work
-> options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
793 ret
= internal_cplus_demangle (work
, mangled
);
794 squangle_mop_up (work
);
799 /* This function performs most of what cplus_demangle use to do, but
800 to be able to demangle a name with a B, K or n code, we need to
801 have a longer term memory of what types have been seen. The original
802 now intializes and cleans up the squangle code info, while internal
803 calls go directly to this routine to avoid resetting that info. */
806 internal_cplus_demangle (work
, mangled
)
807 struct work_stuff
*work
;
813 char *demangled
= NULL
;
815 s1
= work
->constructor
;
816 s2
= work
->destructor
;
817 s3
= work
->static_type
;
818 s4
= work
->type_quals
;
819 work
->constructor
= work
->destructor
= 0;
820 work
->type_quals
= TYPE_UNQUALIFIED
;
821 work
->dllimported
= 0;
823 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
827 /* First check to see if gnu style demangling is active and if the
828 string to be demangled contains a CPLUS_MARKER. If so, attempt to
829 recognize one of the gnu special forms rather than looking for a
830 standard prefix. In particular, don't worry about whether there
831 is a "__" string in the mangled string. Consider "_$_5__foo" for
834 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
836 success
= gnu_special (work
, &mangled
, &decl
);
840 success
= demangle_prefix (work
, &mangled
, &decl
);
842 if (success
&& (*mangled
!= '\0'))
844 success
= demangle_signature (work
, &mangled
, &decl
);
846 if (work
->constructor
== 2)
848 string_prepend (&decl
, "global constructors keyed to ");
849 work
->constructor
= 0;
851 else if (work
->destructor
== 2)
853 string_prepend (&decl
, "global destructors keyed to ");
854 work
->destructor
= 0;
856 else if (work
->dllimported
== 1)
858 string_prepend (&decl
, "import stub for ");
859 work
->dllimported
= 0;
861 demangled
= mop_up (work
, &decl
, success
);
863 work
->constructor
= s1
;
864 work
->destructor
= s2
;
865 work
->static_type
= s3
;
866 work
->type_quals
= s4
;
871 /* Clear out and squangling related storage */
873 squangle_mop_up (work
)
874 struct work_stuff
*work
;
876 /* clean up the B and K type mangling types. */
877 forget_B_and_K_types (work
);
878 if (work
-> btypevec
!= NULL
)
880 free ((char *) work
-> btypevec
);
882 if (work
-> ktypevec
!= NULL
)
884 free ((char *) work
-> ktypevec
);
888 /* Clear out any mangled storage */
891 mop_up (work
, declp
, success
)
892 struct work_stuff
*work
;
896 char *demangled
= NULL
;
898 /* Discard the remembered types, if any. */
901 if (work
-> typevec
!= NULL
)
903 free ((char *) work
-> typevec
);
904 work
-> typevec
= NULL
;
905 work
-> typevec_size
= 0;
907 if (work
->tmpl_argvec
)
911 for (i
= 0; i
< work
->ntmpl_args
; i
++)
912 if (work
->tmpl_argvec
[i
])
913 free ((char*) work
->tmpl_argvec
[i
]);
915 free ((char*) work
->tmpl_argvec
);
916 work
->tmpl_argvec
= NULL
;
918 if (work
->previous_argument
)
920 string_delete (work
->previous_argument
);
921 free ((char*) work
->previous_argument
);
922 work
->previous_argument
= NULL
;
925 /* If demangling was successful, ensure that the demangled string is null
926 terminated and return it. Otherwise, free the demangling decl. */
930 string_delete (declp
);
934 string_appendn (declp
, "", 1);
935 demangled
= declp
-> b
;
944 demangle_signature -- demangle the signature part of a mangled name
949 demangle_signature (struct work_stuff *work, const char **mangled,
954 Consume and demangle the signature portion of the mangled name.
956 DECLP is the string where demangled output is being built. At
957 entry it contains the demangled root name from the mangled name
958 prefix. I.E. either a demangled operator name or the root function
959 name. In some special cases, it may contain nothing.
961 *MANGLED points to the current unconsumed location in the mangled
962 name. As tokens are consumed and demangling is performed, the
963 pointer is updated to continuously point at the next token to
966 Demangling GNU style mangled names is nasty because there is no
967 explicit token that marks the start of the outermost function
971 demangle_signature (work
, mangled
, declp
)
972 struct work_stuff
*work
;
973 const char **mangled
;
979 int expect_return_type
= 0;
980 const char *oldmangled
= NULL
;
984 while (success
&& (**mangled
!= '\0'))
989 oldmangled
= *mangled
;
990 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
992 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
993 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
999 oldmangled
= *mangled
;
1000 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1001 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1009 /* Static member function */
1010 if (oldmangled
== NULL
)
1012 oldmangled
= *mangled
;
1015 work
-> static_type
= 1;
1021 work
->type_quals
|= code_for_qualifier (**mangled
);
1023 /* a qualified member function */
1024 if (oldmangled
== NULL
)
1025 oldmangled
= *mangled
;
1030 /* Local class name follows after "Lnnn_" */
1033 while (**mangled
&& (**mangled
!= '_'))
1044 case '0': case '1': case '2': case '3': case '4':
1045 case '5': case '6': case '7': case '8': case '9':
1046 if (oldmangled
== NULL
)
1048 oldmangled
= *mangled
;
1050 work
->temp_start
= -1; /* uppermost call to demangle_class */
1051 success
= demangle_class (work
, mangled
, declp
);
1054 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1056 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1058 /* EDG and others will have the "F", so we let the loop cycle
1059 if we are looking at one. */
1060 if (**mangled
!= 'F')
1069 success
= do_type (work
, mangled
, &s
);
1072 string_append (&s
, SCOPE_STRING (work
));
1073 string_prepends (declp
, &s
);
1082 /* ARM/HP style demangling includes a specific 'F' character after
1083 the class name. For GNU style, it is just implied. So we can
1084 safely just consume any 'F' at this point and be compatible
1085 with either style. */
1091 /* For lucid/ARM/HP style we have to forget any types we might
1092 have remembered up to this point, since they were not argument
1093 types. GNU style considers all types seen as available for
1094 back references. See comment in demangle_args() */
1096 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1098 forget_types (work
);
1100 success
= demangle_args (work
, mangled
, declp
);
1101 /* After picking off the function args, we expect to either
1102 find the function return type (preceded by an '_') or the
1103 end of the string. */
1104 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1107 /* At this level, we do not care about the return type. */
1108 success
= do_type (work
, mangled
, &tname
);
1109 string_delete (&tname
);
1116 string_init(&trawname
);
1117 string_init(&tname
);
1118 if (oldmangled
== NULL
)
1120 oldmangled
= *mangled
;
1122 success
= demangle_template (work
, mangled
, &tname
,
1126 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1128 string_append (&tname
, SCOPE_STRING (work
));
1130 string_prepends(declp
, &tname
);
1131 if (work
-> destructor
& 1)
1133 string_prepend (&trawname
, "~");
1134 string_appends (declp
, &trawname
);
1135 work
->destructor
-= 1;
1137 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1139 string_appends (declp
, &trawname
);
1140 work
->constructor
-= 1;
1142 string_delete(&trawname
);
1143 string_delete(&tname
);
1149 if (GNU_DEMANGLING
&& expect_return_type
)
1151 /* Read the return type. */
1153 string_init (&return_type
);
1156 success
= do_type (work
, mangled
, &return_type
);
1157 APPEND_BLANK (&return_type
);
1159 string_prepends (declp
, &return_type
);
1160 string_delete (&return_type
);
1164 /* At the outermost level, we cannot have a return type specified,
1165 so if we run into another '_' at this point we are dealing with
1166 a mangled name that is either bogus, or has been mangled by
1167 some algorithm we don't know how to deal with. So just
1168 reject the entire demangling. */
1169 /* However, "_nnn" is an expected suffix for alternate entry point
1170 numbered nnn for a function, with HP aCC, so skip over that
1171 without reporting failure. pai/1997-09-04 */
1175 while (**mangled
&& isdigit ((unsigned char)**mangled
))
1185 /* A G++ template function. Read the template arguments. */
1186 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1188 if (!(work
->constructor
& 1))
1189 expect_return_type
= 1;
1198 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1200 /* Assume we have stumbled onto the first outermost function
1201 argument token, and start processing args. */
1203 success
= demangle_args (work
, mangled
, declp
);
1207 /* Non-GNU demanglers use a specific token to mark the start
1208 of the outermost function argument tokens. Typically 'F',
1209 for ARM/HP-demangling, for example. So if we find something
1210 we are not prepared for, it must be an error. */
1216 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1219 if (success
&& expect_func
)
1222 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1224 forget_types (work
);
1226 success
= demangle_args (work
, mangled
, declp
);
1227 /* Since template include the mangling of their return types,
1228 we must set expect_func to 0 so that we don't try do
1229 demangle more arguments the next time we get here. */
1234 if (success
&& !func_done
)
1236 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1238 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1239 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1240 first case, and need to ensure that the '(void)' gets added to
1241 the current declp. Note that with ARM/HP, the first case
1242 represents the name of a static data member 'foo::bar',
1243 which is in the current declp, so we leave it alone. */
1244 success
= demangle_args (work
, mangled
, declp
);
1247 if (success
&& PRINT_ARG_TYPES
)
1249 if (work
->static_type
)
1250 string_append (declp
, " static");
1251 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1253 APPEND_BLANK (declp
);
1254 string_append (declp
, qualifier_string (work
->type_quals
));
1264 demangle_method_args (work
, mangled
, declp
)
1265 struct work_stuff
*work
;
1266 const char **mangled
;
1271 if (work
-> static_type
)
1273 string_append (declp
, *mangled
+ 1);
1274 *mangled
+= strlen (*mangled
);
1279 success
= demangle_args (work
, mangled
, declp
);
1287 demangle_template_template_parm (work
, mangled
, tname
)
1288 struct work_stuff
*work
;
1289 const char **mangled
;
1298 string_append (tname
, "template <");
1299 /* get size of template parameter list */
1300 if (get_count (mangled
, &r
))
1302 for (i
= 0; i
< r
; i
++)
1306 string_append (tname
, ", ");
1309 /* Z for type parameters */
1310 if (**mangled
== 'Z')
1313 string_append (tname
, "class");
1315 /* z for template parameters */
1316 else if (**mangled
== 'z')
1320 demangle_template_template_parm (work
, mangled
, tname
);
1328 /* temp is initialized in do_type */
1329 success
= do_type (work
, mangled
, &temp
);
1332 string_appends (tname
, &temp
);
1334 string_delete(&temp
);
1344 if (tname
->p
[-1] == '>')
1345 string_append (tname
, " ");
1346 string_append (tname
, "> class");
1351 demangle_integral_value (work
, mangled
, s
)
1352 struct work_stuff
*work
;
1353 const char** mangled
;
1358 if (**mangled
== 'E')
1360 int need_operator
= 0;
1363 string_appendn (s
, "(", 1);
1365 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1374 len
= strlen (*mangled
);
1377 i
< sizeof (optable
) / sizeof (optable
[0]);
1380 size_t l
= strlen (optable
[i
].in
);
1383 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1385 string_appendn (s
, " ", 1);
1386 string_append (s
, optable
[i
].out
);
1387 string_appendn (s
, " ", 1);
1400 success
= demangle_template_value_parm (work
, mangled
, s
,
1404 if (**mangled
!= 'W')
1408 string_appendn (s
, ")", 1);
1412 else if (**mangled
== 'Q' || **mangled
== 'K')
1413 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1418 if (**mangled
== 'm')
1420 string_appendn (s
, "-", 1);
1423 while (isdigit ((unsigned char)**mangled
))
1425 string_appendn (s
, *mangled
, 1);
1435 demangle_template_value_parm (work
, mangled
, s
, tk
)
1436 struct work_stuff
*work
;
1437 const char **mangled
;
1443 if (**mangled
== 'Y')
1445 /* The next argument is a template parameter. */
1449 idx
= consume_count_with_underscores (mangled
);
1451 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1452 || consume_count_with_underscores (mangled
) == -1)
1454 if (work
->tmpl_argvec
)
1455 string_append (s
, work
->tmpl_argvec
[idx
]);
1459 sprintf(buf
, "T%d", idx
);
1460 string_append (s
, buf
);
1463 else if (tk
== tk_integral
)
1464 success
= demangle_integral_value (work
, mangled
, s
);
1465 else if (tk
== tk_char
)
1469 if (**mangled
== 'm')
1471 string_appendn (s
, "-", 1);
1474 string_appendn (s
, "'", 1);
1475 val
= consume_count(mangled
);
1482 string_appendn (s
, &tmp
[0], 1);
1483 string_appendn (s
, "'", 1);
1486 else if (tk
== tk_bool
)
1488 int val
= consume_count (mangled
);
1490 string_appendn (s
, "false", 5);
1492 string_appendn (s
, "true", 4);
1496 else if (tk
== tk_real
)
1498 if (**mangled
== 'm')
1500 string_appendn (s
, "-", 1);
1503 while (isdigit ((unsigned char)**mangled
))
1505 string_appendn (s
, *mangled
, 1);
1508 if (**mangled
== '.') /* fraction */
1510 string_appendn (s
, ".", 1);
1512 while (isdigit ((unsigned char)**mangled
))
1514 string_appendn (s
, *mangled
, 1);
1518 if (**mangled
== 'e') /* exponent */
1520 string_appendn (s
, "e", 1);
1522 while (isdigit ((unsigned char)**mangled
))
1524 string_appendn (s
, *mangled
, 1);
1529 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1531 if (**mangled
== 'Q')
1532 success
= demangle_qualified (work
, mangled
, s
,
1537 int symbol_len
= consume_count (mangled
);
1538 if (symbol_len
== -1)
1540 if (symbol_len
== 0)
1541 string_appendn (s
, "0", 1);
1544 char *p
= xmalloc (symbol_len
+ 1), *q
;
1545 strncpy (p
, *mangled
, symbol_len
);
1546 p
[symbol_len
] = '\0';
1547 /* We use cplus_demangle here, rather than
1548 internal_cplus_demangle, because the name of the entity
1549 mangled here does not make use of any of the squangling
1550 or type-code information we have built up thus far; it is
1551 mangled independently. */
1552 q
= cplus_demangle (p
, work
->options
);
1553 if (tk
== tk_pointer
)
1554 string_appendn (s
, "&", 1);
1555 /* FIXME: Pointer-to-member constants should get a
1556 qualifying class name here. */
1559 string_append (s
, q
);
1563 string_append (s
, p
);
1566 *mangled
+= symbol_len
;
1573 /* Demangle the template name in MANGLED. The full name of the
1574 template (e.g., S<int>) is placed in TNAME. The name without the
1575 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1576 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1577 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1578 the tmeplate is remembered in the list of back-referenceable
1582 demangle_template (work
, mangled
, tname
, trawname
, is_type
, remember
)
1583 struct work_stuff
*work
;
1584 const char **mangled
;
1595 int is_java_array
= 0;
1603 bindex
= register_Btype (work
);
1605 /* get template name */
1606 if (**mangled
== 'z')
1612 idx
= consume_count_with_underscores (mangled
);
1614 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1615 || consume_count_with_underscores (mangled
) == -1)
1618 if (work
->tmpl_argvec
)
1620 string_append (tname
, work
->tmpl_argvec
[idx
]);
1622 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1627 sprintf(buf
, "T%d", idx
);
1628 string_append (tname
, buf
);
1630 string_append (trawname
, buf
);
1635 if ((r
= consume_count (mangled
)) <= 0
1636 || (int) strlen (*mangled
) < r
)
1640 is_java_array
= (work
-> options
& DMGL_JAVA
)
1641 && strncmp (*mangled
, "JArray1Z", 8) == 0;
1642 if (! is_java_array
)
1644 string_appendn (tname
, *mangled
, r
);
1647 string_appendn (trawname
, *mangled
, r
);
1652 string_append (tname
, "<");
1653 /* get size of template parameter list */
1654 if (!get_count (mangled
, &r
))
1660 /* Create an array for saving the template argument values. */
1661 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
1662 work
->ntmpl_args
= r
;
1663 for (i
= 0; i
< r
; i
++)
1664 work
->tmpl_argvec
[i
] = 0;
1666 for (i
= 0; i
< r
; i
++)
1670 string_append (tname
, ", ");
1672 /* Z for type parameters */
1673 if (**mangled
== 'Z')
1676 /* temp is initialized in do_type */
1677 success
= do_type (work
, mangled
, &temp
);
1680 string_appends (tname
, &temp
);
1684 /* Save the template argument. */
1685 int len
= temp
.p
- temp
.b
;
1686 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1687 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
1688 work
->tmpl_argvec
[i
][len
] = '\0';
1691 string_delete(&temp
);
1697 /* z for template parameters */
1698 else if (**mangled
== 'z')
1702 success
= demangle_template_template_parm (work
, mangled
, tname
);
1705 && (r2
= consume_count (mangled
)) > 0
1706 && (int) strlen (*mangled
) >= r2
)
1708 string_append (tname
, " ");
1709 string_appendn (tname
, *mangled
, r2
);
1712 /* Save the template argument. */
1714 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1715 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
1716 work
->tmpl_argvec
[i
][len
] = '\0';
1730 /* otherwise, value parameter */
1732 /* temp is initialized in do_type */
1733 success
= do_type (work
, mangled
, &temp
);
1734 string_delete(&temp
);
1746 success
= demangle_template_value_parm (work
, mangled
, s
,
1747 (type_kind_t
) success
);
1759 int len
= s
->p
- s
->b
;
1760 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1761 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
1762 work
->tmpl_argvec
[i
][len
] = '\0';
1764 string_appends (tname
, s
);
1772 string_append (tname
, "[]");
1776 if (tname
->p
[-1] == '>')
1777 string_append (tname
, " ");
1778 string_append (tname
, ">");
1781 if (is_type
&& remember
)
1782 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
1785 if (work -> static_type)
1787 string_append (declp, *mangled + 1);
1788 *mangled += strlen (*mangled);
1793 success = demangle_args (work, mangled, declp);
1801 arm_pt (work
, mangled
, n
, anchor
, args
)
1802 struct work_stuff
*work
;
1803 const char *mangled
;
1805 const char **anchor
, **args
;
1807 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1808 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1809 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= mystrstr (mangled
, "__pt__")))
1812 *args
= *anchor
+ 6;
1813 len
= consume_count (args
);
1816 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1822 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
1824 if ((*anchor
= mystrstr (mangled
, "__tm__"))
1825 || (*anchor
= mystrstr (mangled
, "__ps__"))
1826 || (*anchor
= mystrstr (mangled
, "__pt__")))
1829 *args
= *anchor
+ 6;
1830 len
= consume_count (args
);
1833 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1839 else if ((*anchor
= mystrstr (mangled
, "__S")))
1842 *args
= *anchor
+ 3;
1843 len
= consume_count (args
);
1846 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1858 demangle_arm_hp_template (work
, mangled
, n
, declp
)
1859 struct work_stuff
*work
;
1860 const char **mangled
;
1866 const char *e
= *mangled
+ n
;
1869 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1871 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
1873 char *start_spec_args
= NULL
;
1875 /* First check for and omit template specialization pseudo-arguments,
1876 such as in "Spec<#1,#1.*>" */
1877 start_spec_args
= strchr (*mangled
, '<');
1878 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
1879 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
1881 string_appendn (declp
, *mangled
, n
);
1882 (*mangled
) += n
+ 1;
1884 if (work
->temp_start
== -1) /* non-recursive call */
1885 work
->temp_start
= declp
->p
- declp
->b
;
1886 string_append (declp
, "<");
1889 string_clear (&arg
);
1893 /* 'T' signals a type parameter */
1895 if (!do_type (work
, mangled
, &arg
))
1896 goto hpacc_template_args_done
;
1901 /* 'U' or 'S' signals an integral value */
1902 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
1903 goto hpacc_template_args_done
;
1907 /* 'A' signals a named constant expression (literal) */
1908 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
1909 goto hpacc_template_args_done
;
1913 /* Today, 1997-09-03, we have only the above types
1914 of template parameters */
1915 /* FIXME: maybe this should fail and return null */
1916 goto hpacc_template_args_done
;
1918 string_appends (declp
, &arg
);
1919 /* Check if we're at the end of template args.
1920 0 if at end of static member of template class,
1921 _ if done with template args for a function */
1922 if ((**mangled
== '\000') || (**mangled
== '_'))
1925 string_append (declp
, ",");
1927 hpacc_template_args_done
:
1928 string_append (declp
, ">");
1929 string_delete (&arg
);
1930 if (**mangled
== '_')
1934 /* ARM template? (Also handles HP cfront extensions) */
1935 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
1940 string_appendn (declp
, *mangled
, p
- *mangled
);
1941 if (work
->temp_start
== -1) /* non-recursive call */
1942 work
->temp_start
= declp
->p
- declp
->b
;
1943 string_append (declp
, "<");
1944 /* should do error checking here */
1946 string_clear (&arg
);
1948 /* Check for type or literal here */
1951 /* HP cfront extensions to ARM for template args */
1952 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1953 /* FIXME: We handle only numeric literals for HP cfront */
1955 /* A typed constant value follows */
1957 if (!do_type (work
, &args
, &type_str
))
1958 goto cfront_template_args_done
;
1959 string_append (&arg
, "(");
1960 string_appends (&arg
, &type_str
);
1961 string_append (&arg
, ")");
1963 goto cfront_template_args_done
;
1965 /* Now snarf a literal value following 'L' */
1966 if (!snarf_numeric_literal (&args
, &arg
))
1967 goto cfront_template_args_done
;
1971 /* Snarf a literal following 'L' */
1973 if (!snarf_numeric_literal (&args
, &arg
))
1974 goto cfront_template_args_done
;
1977 /* Not handling other HP cfront stuff */
1978 if (!do_type (work
, &args
, &arg
))
1979 goto cfront_template_args_done
;
1981 string_appends (declp
, &arg
);
1982 string_append (declp
, ",");
1984 cfront_template_args_done
:
1985 string_delete (&arg
);
1987 --declp
->p
; /* remove extra comma */
1988 string_append (declp
, ">");
1990 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
1991 && (*mangled
)[9] == 'N'
1992 && (*mangled
)[8] == (*mangled
)[10]
1993 && strchr (cplus_markers
, (*mangled
)[8]))
1995 /* A member of the anonymous namespace. */
1996 string_append (declp
, "{anonymous}");
2000 if (work
->temp_start
== -1) /* non-recursive call only */
2001 work
->temp_start
= 0; /* disable in recursive calls */
2002 string_appendn (declp
, *mangled
, n
);
2007 /* Extract a class name, possibly a template with arguments, from the
2008 mangled string; qualifiers, local class indicators, etc. have
2009 already been dealt with */
2012 demangle_class_name (work
, mangled
, declp
)
2013 struct work_stuff
*work
;
2014 const char **mangled
;
2020 n
= consume_count (mangled
);
2023 if ((int) strlen (*mangled
) >= n
)
2025 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2036 demangle_class -- demangle a mangled class sequence
2041 demangle_class (struct work_stuff *work, const char **mangled,
2046 DECLP points to the buffer into which demangling is being done.
2048 *MANGLED points to the current token to be demangled. On input,
2049 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2050 On exit, it points to the next token after the mangled class on
2051 success, or the first unconsumed token on failure.
2053 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2054 we are demangling a constructor or destructor. In this case
2055 we prepend "class::class" or "class::~class" to DECLP.
2057 Otherwise, we prepend "class::" to the current DECLP.
2059 Reset the constructor/destructor flags once they have been
2060 "consumed". This allows demangle_class to be called later during
2061 the same demangling, to do normal class demangling.
2063 Returns 1 if demangling is successful, 0 otherwise.
2068 demangle_class (work
, mangled
, declp
)
2069 struct work_stuff
*work
;
2070 const char **mangled
;
2076 char *save_class_name_end
= 0;
2078 string_init (&class_name
);
2079 btype
= register_Btype (work
);
2080 if (demangle_class_name (work
, mangled
, &class_name
))
2082 save_class_name_end
= class_name
.p
;
2083 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2085 /* adjust so we don't include template args */
2086 if (work
->temp_start
&& (work
->temp_start
!= -1))
2088 class_name
.p
= class_name
.b
+ work
->temp_start
;
2090 string_prepends (declp
, &class_name
);
2091 if (work
-> destructor
& 1)
2093 string_prepend (declp
, "~");
2094 work
-> destructor
-= 1;
2098 work
-> constructor
-= 1;
2101 class_name
.p
= save_class_name_end
;
2102 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2103 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2104 string_prepend (declp
, SCOPE_STRING (work
));
2105 string_prepends (declp
, &class_name
);
2108 string_delete (&class_name
);
2116 demangle_prefix -- consume the mangled name prefix and find signature
2121 demangle_prefix (struct work_stuff *work, const char **mangled,
2126 Consume and demangle the prefix of the mangled name.
2128 DECLP points to the string buffer into which demangled output is
2129 placed. On entry, the buffer is empty. On exit it contains
2130 the root function name, the demangled operator name, or in some
2131 special cases either nothing or the completely demangled result.
2133 MANGLED points to the current pointer into the mangled name. As each
2134 token of the mangled name is consumed, it is updated. Upon entry
2135 the current mangled name pointer points to the first character of
2136 the mangled name. Upon exit, it should point to the first character
2137 of the signature if demangling was successful, or to the first
2138 unconsumed character if demangling of the prefix was unsuccessful.
2140 Returns 1 on success, 0 otherwise.
2144 demangle_prefix (work
, mangled
, declp
)
2145 struct work_stuff
*work
;
2146 const char **mangled
;
2153 if (strlen(*mangled
) > 6
2154 && (strncmp(*mangled
, "_imp__", 6) == 0
2155 || strncmp(*mangled
, "__imp_", 6) == 0))
2157 /* it's a symbol imported from a PE dynamic library. Check for both
2158 new style prefix _imp__ and legacy __imp_ used by older versions
2161 work
->dllimported
= 1;
2163 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2165 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2166 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2168 if ((*mangled
)[9] == 'D')
2170 /* it's a GNU global destructor to be executed at program exit */
2172 work
->destructor
= 2;
2173 if (gnu_special (work
, mangled
, declp
))
2176 else if ((*mangled
)[9] == 'I')
2178 /* it's a GNU global constructor to be executed at program init */
2180 work
->constructor
= 2;
2181 if (gnu_special (work
, mangled
, declp
))
2186 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2188 /* it's a ARM global destructor to be executed at program exit */
2190 work
->destructor
= 2;
2192 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2194 /* it's a ARM global constructor to be executed at program initial */
2196 work
->constructor
= 2;
2199 /* This block of code is a reduction in strength time optimization
2201 scan = mystrstr (*mangled, "__"); */
2207 scan
= strchr (scan
, '_');
2208 } while (scan
!= NULL
&& *++scan
!= '_');
2210 if (scan
!= NULL
) --scan
;
2215 /* We found a sequence of two or more '_', ensure that we start at
2216 the last pair in the sequence. */
2217 i
= strspn (scan
, "_");
2228 else if (work
-> static_type
)
2230 if (!isdigit ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2235 else if ((scan
== *mangled
)
2236 && (isdigit ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2237 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2239 /* The ARM says nothing about the mangling of local variables.
2240 But cfront mangles local variables by prepending __<nesting_level>
2241 to them. As an extension to ARM demangling we handle this case. */
2242 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2243 && isdigit ((unsigned char)scan
[2]))
2245 *mangled
= scan
+ 2;
2246 consume_count (mangled
);
2247 string_append (declp
, *mangled
);
2248 *mangled
+= strlen (*mangled
);
2253 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2254 names like __Q2_3foo3bar for nested type names. So don't accept
2255 this style of constructor for cfront demangling. A GNU
2256 style member-template constructor starts with 'H'. */
2257 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2258 work
-> constructor
+= 1;
2259 *mangled
= scan
+ 2;
2262 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2264 /* Cfront-style parameterized type. Handled later as a signature. */
2268 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2270 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2271 || (scan
[2] == 'p' && scan
[3] == 's')
2272 || (scan
[2] == 'p' && scan
[3] == 't')))
2274 /* EDG-style parameterized type. Handled later as a signature. */
2278 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2280 else if ((scan
== *mangled
) && !isdigit ((unsigned char)scan
[2])
2281 && (scan
[2] != 't'))
2283 /* Mangled name starts with "__". Skip over any leading '_' characters,
2284 then find the next "__" that separates the prefix from the signature.
2286 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2287 || (arm_special (mangled
, declp
) == 0))
2289 while (*scan
== '_')
2293 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2295 /* No separator (I.E. "__not_mangled"), or empty signature
2296 (I.E. "__not_mangled_either__") */
2303 /* Look for the LAST occurrence of __, allowing names to
2304 have the '__' sequence embedded in them. */
2305 if (!(ARM_DEMANGLING
|| HP_DEMANGLING
))
2307 while ((tmp
= mystrstr (scan
+ 2, "__")) != NULL
)
2310 if (*(scan
+ 2) == '\0')
2313 demangle_function_name (work
, mangled
, declp
, scan
);
2317 else if (*(scan
+ 2) != '\0')
2319 /* Mangled name does not start with "__" but does have one somewhere
2320 in there with non empty stuff after it. Looks like a global
2322 demangle_function_name (work
, mangled
, declp
, scan
);
2326 /* Doesn't look like a mangled name */
2330 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2332 string_append (declp
, *mangled
);
2333 *mangled
+= strlen (*mangled
);
2343 gnu_special -- special handling of gnu mangled strings
2348 gnu_special (struct work_stuff *work, const char **mangled,
2354 Process some special GNU style mangling forms that don't fit
2355 the normal pattern. For example:
2357 _$_3foo (destructor for class foo)
2358 _vt$foo (foo virtual table)
2359 _vt$foo$bar (foo::bar virtual table)
2360 __vt_foo (foo virtual table, new style with thunks)
2361 _3foo$varname (static data member)
2362 _Q22rs2tu$vw (static data member)
2363 __t6vector1Zii (constructor with template)
2364 __thunk_4__$_7ostream (virtual function thunk)
2368 gnu_special (work
, mangled
, declp
)
2369 struct work_stuff
*work
;
2370 const char **mangled
;
2377 if ((*mangled
)[0] == '_'
2378 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2379 && (*mangled
)[2] == '_')
2381 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2383 work
-> destructor
+= 1;
2385 else if ((*mangled
)[0] == '_'
2386 && (((*mangled
)[1] == '_'
2387 && (*mangled
)[2] == 'v'
2388 && (*mangled
)[3] == 't'
2389 && (*mangled
)[4] == '_')
2390 || ((*mangled
)[1] == 'v'
2391 && (*mangled
)[2] == 't'
2392 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2394 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2395 and create the decl. Note that we consume the entire mangled
2396 input string, which means that demangle_signature has no work
2398 if ((*mangled
)[2] == 'v')
2399 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2401 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2402 while (**mangled
!= '\0')
2408 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2411 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2415 if (isdigit((unsigned char)*mangled
[0]))
2417 n
= consume_count(mangled
);
2418 /* We may be seeing a too-large size, or else a
2419 ".<digits>" indicating a static local symbol. In
2420 any case, declare victory and move on; *don't* try
2421 to use n to allocate. */
2422 if (n
> (int) strlen (*mangled
))
2430 n
= strcspn (*mangled
, cplus_markers
);
2432 string_appendn (declp
, *mangled
, n
);
2436 p
= strpbrk (*mangled
, cplus_markers
);
2437 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2441 string_append (declp
, SCOPE_STRING (work
));
2452 string_append (declp
, " virtual table");
2454 else if ((*mangled
)[0] == '_'
2455 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2456 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2458 /* static data member, "_3foo$varname" for example */
2464 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2467 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2470 n
= consume_count (mangled
);
2471 if (n
< 0 || n
> (long) strlen (*mangled
))
2476 string_appendn (declp
, *mangled
, n
);
2479 if (success
&& (p
== *mangled
))
2481 /* Consumed everything up to the cplus_marker, append the
2484 string_append (declp
, SCOPE_STRING (work
));
2485 n
= strlen (*mangled
);
2486 string_appendn (declp
, *mangled
, n
);
2494 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2499 delta
= consume_count (mangled
);
2504 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2509 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2510 string_append (declp
, buf
);
2511 string_append (declp
, method
);
2513 n
= strlen (*mangled
);
2522 else if (strncmp (*mangled
, "__t", 3) == 0
2523 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2525 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2531 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2534 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2537 success
= demangle_fund_type (work
, mangled
, declp
);
2540 if (success
&& **mangled
!= '\0')
2543 string_append (declp
, p
);
2553 recursively_demangle(work
, mangled
, result
, namelength
)
2554 struct work_stuff
*work
;
2555 const char **mangled
;
2559 char * recurse
= (char *)NULL
;
2560 char * recurse_dem
= (char *)NULL
;
2562 recurse
= (char *) xmalloc (namelength
+ 1);
2563 memcpy (recurse
, *mangled
, namelength
);
2564 recurse
[namelength
] = '\000';
2566 recurse_dem
= cplus_demangle (recurse
, work
->options
);
2570 string_append (result
, recurse_dem
);
2575 string_appendn (result
, *mangled
, namelength
);
2578 *mangled
+= namelength
;
2585 arm_special -- special handling of ARM/lucid mangled strings
2590 arm_special (const char **mangled,
2596 Process some special ARM style mangling forms that don't fit
2597 the normal pattern. For example:
2599 __vtbl__3foo (foo virtual table)
2600 __vtbl__3foo__3bar (bar::foo virtual table)
2605 arm_special (mangled
, declp
)
2606 const char **mangled
;
2613 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
2615 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2616 and create the decl. Note that we consume the entire mangled
2617 input string, which means that demangle_signature has no work
2619 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
2620 while (*scan
!= '\0') /* first check it can be demangled */
2622 n
= consume_count (&scan
);
2625 return (0); /* no good */
2628 if (scan
[0] == '_' && scan
[1] == '_')
2633 (*mangled
) += ARM_VTABLE_STRLEN
;
2634 while (**mangled
!= '\0')
2636 n
= consume_count (mangled
);
2638 || n
> (long) strlen (*mangled
))
2640 string_prependn (declp
, *mangled
, n
);
2642 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
2644 string_prepend (declp
, "::");
2648 string_append (declp
, " virtual table");
2661 demangle_qualified -- demangle 'Q' qualified name strings
2666 demangle_qualified (struct work_stuff *, const char *mangled,
2667 string *result, int isfuncname, int append);
2671 Demangle a qualified name, such as "Q25Outer5Inner" which is
2672 the mangled form of "Outer::Inner". The demangled output is
2673 prepended or appended to the result string according to the
2674 state of the append flag.
2676 If isfuncname is nonzero, then the qualified name we are building
2677 is going to be used as a member function name, so if it is a
2678 constructor or destructor function, append an appropriate
2679 constructor or destructor name. I.E. for the above example,
2680 the result for use as a constructor is "Outer::Inner::Inner"
2681 and the result for use as a destructor is "Outer::Inner::~Inner".
2685 Numeric conversion is ASCII dependent (FIXME).
2690 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
2691 struct work_stuff
*work
;
2692 const char **mangled
;
2703 int bindex
= register_Btype (work
);
2705 /* We only make use of ISFUNCNAME if the entity is a constructor or
2707 isfuncname
= (isfuncname
2708 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
2710 string_init (&temp
);
2711 string_init (&last_name
);
2713 if ((*mangled
)[0] == 'K')
2715 /* Squangling qualified name reuse */
2718 idx
= consume_count_with_underscores (mangled
);
2719 if (idx
== -1 || idx
>= work
-> numk
)
2722 string_append (&temp
, work
-> ktypevec
[idx
]);
2725 switch ((*mangled
)[1])
2728 /* GNU mangled name with more than 9 classes. The count is preceded
2729 by an underscore (to distinguish it from the <= 9 case) and followed
2730 by an underscore. */
2732 qualifiers
= atoi (p
);
2733 if (!isdigit ((unsigned char)*p
) || *p
== '0')
2736 /* Skip the digits. */
2737 while (isdigit ((unsigned char)*p
))
2755 /* The count is in a single digit. */
2756 num
[0] = (*mangled
)[1];
2758 qualifiers
= atoi (num
);
2760 /* If there is an underscore after the digit, skip it. This is
2761 said to be for ARM-qualified names, but the ARM makes no
2762 mention of such an underscore. Perhaps cfront uses one. */
2763 if ((*mangled
)[2] == '_')
2778 /* Pick off the names and collect them in the temp buffer in the order
2779 in which they are found, separated by '::'. */
2781 while (qualifiers
-- > 0)
2784 string_clear (&last_name
);
2786 if (*mangled
[0] == '_')
2789 if (*mangled
[0] == 't')
2791 /* Here we always append to TEMP since we will want to use
2792 the template name without the template parameters as a
2793 constructor or destructor name. The appropriate
2794 (parameter-less) value is returned by demangle_template
2795 in LAST_NAME. We do not remember the template type here,
2796 in order to match the G++ mangling algorithm. */
2797 success
= demangle_template(work
, mangled
, &temp
,
2802 else if (*mangled
[0] == 'K')
2806 idx
= consume_count_with_underscores (mangled
);
2807 if (idx
== -1 || idx
>= work
->numk
)
2810 string_append (&temp
, work
->ktypevec
[idx
]);
2813 if (!success
) break;
2820 /* Now recursively demangle the qualifier
2821 * This is necessary to deal with templates in
2822 * mangling styles like EDG */
2823 namelength
= consume_count (mangled
);
2824 if (namelength
== -1)
2829 recursively_demangle(work
, mangled
, &temp
, namelength
);
2833 success
= do_type (work
, mangled
, &last_name
);
2836 string_appends (&temp
, &last_name
);
2841 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
2844 string_append (&temp
, SCOPE_STRING (work
));
2847 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
2849 /* If we are using the result as a function name, we need to append
2850 the appropriate '::' separated constructor or destructor name.
2851 We do this here because this is the most convenient place, where
2852 we already have a pointer to the name and the length of the name. */
2856 string_append (&temp
, SCOPE_STRING (work
));
2857 if (work
-> destructor
& 1)
2858 string_append (&temp
, "~");
2859 string_appends (&temp
, &last_name
);
2862 /* Now either prepend the temp buffer to the result, or append it,
2863 depending upon the state of the append flag. */
2866 string_appends (result
, &temp
);
2869 if (!STRING_EMPTY (result
))
2870 string_append (&temp
, SCOPE_STRING (work
));
2871 string_prepends (result
, &temp
);
2874 string_delete (&last_name
);
2875 string_delete (&temp
);
2883 get_count -- convert an ascii count to integer, consuming tokens
2888 get_count (const char **type, int *count)
2892 Assume that *type points at a count in a mangled name; set
2893 *count to its value, and set *type to the next character after
2894 the count. There are some weird rules in effect here.
2896 If *type does not point at a string of digits, return zero.
2898 If *type points at a string of digits followed by an
2899 underscore, set *count to their value as an integer, advance
2900 *type to point *after the underscore, and return 1.
2902 If *type points at a string of digits not followed by an
2903 underscore, consume only the first digit. Set *count to its
2904 value as an integer, leave *type pointing after that digit,
2907 The excuse for this odd behavior: in the ARM and HP demangling
2908 styles, a type can be followed by a repeat count of the form
2911 `x' is a single digit specifying how many additional copies
2912 of the type to append to the argument list, and
2914 `y' is one or more digits, specifying the zero-based index of
2915 the first repeated argument in the list. Yes, as you're
2916 unmangling the name you can figure this out yourself, but
2919 So, for example, in `bar__3fooFPiN51', the first argument is a
2920 pointer to an integer (`Pi'), and then the next five arguments
2921 are the same (`N5'), and the first repeat is the function's
2922 second argument (`1').
2926 get_count (type
, count
)
2933 if (!isdigit ((unsigned char)**type
))
2939 *count
= **type
- '0';
2941 if (isdigit ((unsigned char)**type
))
2951 while (isdigit ((unsigned char)*p
));
2962 /* RESULT will be initialised here; it will be freed on failure. The
2963 value returned is really a type_kind_t. */
2966 do_type (work
, mangled
, result
)
2967 struct work_stuff
*work
;
2968 const char **mangled
;
2975 const char *remembered_type
;
2978 type_kind_t tk
= tk_none
;
2980 string_init (&btype
);
2981 string_init (&decl
);
2982 string_init (result
);
2986 while (success
&& !done
)
2992 /* A pointer type */
2996 if (! (work
-> options
& DMGL_JAVA
))
2997 string_prepend (&decl
, "*");
3002 /* A reference type */
3005 string_prepend (&decl
, "&");
3014 if (!STRING_EMPTY (&decl
)
3015 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3017 string_prepend (&decl
, "(");
3018 string_append (&decl
, ")");
3020 string_append (&decl
, "[");
3021 if (**mangled
!= '_')
3022 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3024 if (**mangled
== '_')
3026 string_append (&decl
, "]");
3030 /* A back reference to a previously seen type */
3033 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3039 remembered_type
= work
-> typevec
[n
];
3040 mangled
= &remembered_type
;
3047 if (!STRING_EMPTY (&decl
)
3048 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3050 string_prepend (&decl
, "(");
3051 string_append (&decl
, ")");
3053 /* After picking off the function args, we expect to either find the
3054 function return type (preceded by an '_') or the end of the
3056 if (!demangle_nested_args (work
, mangled
, &decl
)
3057 || (**mangled
!= '_' && **mangled
!= '\0'))
3062 if (success
&& (**mangled
== '_'))
3069 type_quals
= TYPE_UNQUALIFIED
;
3071 member
= **mangled
== 'M';
3074 string_append (&decl
, ")");
3075 string_prepend (&decl
, SCOPE_STRING (work
));
3076 if (isdigit ((unsigned char)**mangled
))
3078 n
= consume_count (mangled
);
3080 || (int) strlen (*mangled
) < n
)
3085 string_prependn (&decl
, *mangled
, n
);
3088 else if (**mangled
== 'X' || **mangled
== 'Y')
3091 do_type (work
, mangled
, &temp
);
3092 string_prepends (&decl
, &temp
);
3094 else if (**mangled
== 't')
3097 string_init (&temp
);
3098 success
= demangle_template (work
, mangled
, &temp
,
3102 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3103 string_clear (&temp
);
3114 string_prepend (&decl
, "(");
3122 type_quals
|= code_for_qualifier (**mangled
);
3130 if (*(*mangled
)++ != 'F')
3136 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3137 || **mangled
!= '_')
3143 if (! PRINT_ANSI_QUALIFIERS
)
3147 if (type_quals
!= TYPE_UNQUALIFIED
)
3149 APPEND_BLANK (&decl
);
3150 string_append (&decl
, qualifier_string (type_quals
));
3161 if (PRINT_ANSI_QUALIFIERS
)
3163 if (!STRING_EMPTY (&decl
))
3164 string_prepend (&decl
, " ");
3166 string_prepend (&decl
, demangle_qualifier (**mangled
));
3181 if (success
) switch (**mangled
)
3183 /* A qualified name, such as "Outer::Inner". */
3187 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3191 /* A back reference to a previously seen squangled type */
3194 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3197 string_append (result
, work
->btypevec
[n
]);
3202 /* A template parm. We substitute the corresponding argument. */
3207 idx
= consume_count_with_underscores (mangled
);
3210 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3211 || consume_count_with_underscores (mangled
) == -1)
3217 if (work
->tmpl_argvec
)
3218 string_append (result
, work
->tmpl_argvec
[idx
]);
3222 sprintf(buf
, "T%d", idx
);
3223 string_append (result
, buf
);
3231 success
= demangle_fund_type (work
, mangled
, result
);
3233 tk
= (type_kind_t
) success
;
3239 if (!STRING_EMPTY (&decl
))
3241 string_append (result
, " ");
3242 string_appends (result
, &decl
);
3246 string_delete (result
);
3247 string_delete (&decl
);
3250 /* Assume an integral type, if we're not sure. */
3251 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3256 /* Given a pointer to a type string that represents a fundamental type
3257 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3258 string in which the demangled output is being built in RESULT, and
3259 the WORK structure, decode the types and add them to the result.
3264 "Sl" => "signed long"
3265 "CUs" => "const unsigned short"
3267 The value returned is really a type_kind_t. */
3270 demangle_fund_type (work
, mangled
, result
)
3271 struct work_stuff
*work
;
3272 const char **mangled
;
3280 type_kind_t tk
= tk_integral
;
3282 string_init (&btype
);
3284 /* First pick off any type qualifiers. There can be more than one. */
3293 if (PRINT_ANSI_QUALIFIERS
)
3295 if (!STRING_EMPTY (result
))
3296 string_prepend (result
, " ");
3297 string_prepend (result
, demangle_qualifier (**mangled
));
3303 APPEND_BLANK (result
);
3304 string_append (result
, "unsigned");
3306 case 'S': /* signed char only */
3308 APPEND_BLANK (result
);
3309 string_append (result
, "signed");
3313 APPEND_BLANK (result
);
3314 string_append (result
, "__complex");
3322 /* Now pick off the fundamental type. There can be only one. */
3331 APPEND_BLANK (result
);
3332 string_append (result
, "void");
3336 APPEND_BLANK (result
);
3337 string_append (result
, "long long");
3341 APPEND_BLANK (result
);
3342 string_append (result
, "long");
3346 APPEND_BLANK (result
);
3347 string_append (result
, "int");
3351 APPEND_BLANK (result
);
3352 string_append (result
, "short");
3356 APPEND_BLANK (result
);
3357 string_append (result
, "bool");
3362 APPEND_BLANK (result
);
3363 string_append (result
, "char");
3368 APPEND_BLANK (result
);
3369 string_append (result
, "wchar_t");
3374 APPEND_BLANK (result
);
3375 string_append (result
, "long double");
3380 APPEND_BLANK (result
);
3381 string_append (result
, "double");
3386 APPEND_BLANK (result
);
3387 string_append (result
, "float");
3392 if (!isdigit ((unsigned char)**mangled
))
3399 if (**mangled
== '_')
3404 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3407 if (**mangled
!= '_')
3417 strncpy (buf
, *mangled
, 2);
3419 *mangled
+= min (strlen (*mangled
), 2);
3421 sscanf (buf
, "%x", &dec
);
3422 sprintf (buf
, "int%i_t", dec
);
3423 APPEND_BLANK (result
);
3424 string_append (result
, buf
);
3428 /* An explicit type, such as "6mytype" or "7integer" */
3440 int bindex
= register_Btype (work
);
3442 string_init (&btype
);
3443 if (demangle_class_name (work
, mangled
, &btype
)) {
3444 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3445 APPEND_BLANK (result
);
3446 string_appends (result
, &btype
);
3450 string_delete (&btype
);
3455 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3456 string_appends (result
, &btype
);
3464 return success
? ((int) tk
) : 0;
3468 /* Handle a template's value parameter for HP aCC (extension from ARM)
3469 **mangled points to 'S' or 'U' */
3472 do_hpacc_template_const_value (work
, mangled
, result
)
3473 struct work_stuff
*work ATTRIBUTE_UNUSED
;
3474 const char **mangled
;
3479 if (**mangled
!= 'U' && **mangled
!= 'S')
3482 unsigned_const
= (**mangled
== 'U');
3489 string_append (result
, "-");
3495 /* special case for -2^31 */
3496 string_append (result
, "-2147483648");
3503 /* We have to be looking at an integer now */
3504 if (!(isdigit ((unsigned char)**mangled
)))
3507 /* We only deal with integral values for template
3508 parameters -- so it's OK to look only for digits */
3509 while (isdigit ((unsigned char)**mangled
))
3511 char_str
[0] = **mangled
;
3512 string_append (result
, char_str
);
3517 string_append (result
, "U");
3519 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3520 with L or LL suffixes. pai/1997-09-03 */
3522 return 1; /* success */
3525 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3526 **mangled is pointing to the 'A' */
3529 do_hpacc_template_literal (work
, mangled
, result
)
3530 struct work_stuff
*work
;
3531 const char **mangled
;
3534 int literal_len
= 0;
3538 if (**mangled
!= 'A')
3543 literal_len
= consume_count (mangled
);
3545 if (literal_len
<= 0)
3548 /* Literal parameters are names of arrays, functions, etc. and the
3549 canonical representation uses the address operator */
3550 string_append (result
, "&");
3552 /* Now recursively demangle the literal name */
3553 recurse
= (char *) xmalloc (literal_len
+ 1);
3554 memcpy (recurse
, *mangled
, literal_len
);
3555 recurse
[literal_len
] = '\000';
3557 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3561 string_append (result
, recurse_dem
);
3566 string_appendn (result
, *mangled
, literal_len
);
3568 (*mangled
) += literal_len
;
3575 snarf_numeric_literal (args
, arg
)
3582 string_append (arg
, char_str
);
3585 else if (**args
== '+')
3588 if (!isdigit ((unsigned char)**args
))
3591 while (isdigit ((unsigned char)**args
))
3593 char_str
[0] = **args
;
3594 string_append (arg
, char_str
);
3601 /* Demangle the next argument, given by MANGLED into RESULT, which
3602 *should be an uninitialized* string. It will be initialized here,
3603 and free'd should anything go wrong. */
3606 do_arg (work
, mangled
, result
)
3607 struct work_stuff
*work
;
3608 const char **mangled
;
3611 /* Remember where we started so that we can record the type, for
3612 non-squangling type remembering. */
3613 const char *start
= *mangled
;
3615 string_init (result
);
3617 if (work
->nrepeats
> 0)
3621 if (work
->previous_argument
== 0)
3624 /* We want to reissue the previous type in this argument list. */
3625 string_appends (result
, work
->previous_argument
);
3629 if (**mangled
== 'n')
3631 /* A squangling-style repeat. */
3633 work
->nrepeats
= consume_count(mangled
);
3635 if (work
->nrepeats
<= 0)
3636 /* This was not a repeat count after all. */
3639 if (work
->nrepeats
> 9)
3641 if (**mangled
!= '_')
3642 /* The repeat count should be followed by an '_' in this
3649 /* Now, the repeat is all set up. */
3650 return do_arg (work
, mangled
, result
);
3653 /* Save the result in WORK->previous_argument so that we can find it
3654 if it's repeated. Note that saving START is not good enough: we
3655 do not want to add additional types to the back-referenceable
3656 type vector when processing a repeated type. */
3657 if (work
->previous_argument
)
3658 string_clear (work
->previous_argument
);
3661 work
->previous_argument
= (string
*) xmalloc (sizeof (string
));
3662 string_init (work
->previous_argument
);
3665 if (!do_type (work
, mangled
, work
->previous_argument
))
3668 string_appends (result
, work
->previous_argument
);
3670 remember_type (work
, start
, *mangled
- start
);
3675 remember_type (work
, start
, len
)
3676 struct work_stuff
*work
;
3682 if (work
->forgetting_types
)
3685 if (work
-> ntypes
>= work
-> typevec_size
)
3687 if (work
-> typevec_size
== 0)
3689 work
-> typevec_size
= 3;
3691 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
3695 work
-> typevec_size
*= 2;
3697 = (char **) xrealloc ((char *)work
-> typevec
,
3698 sizeof (char *) * work
-> typevec_size
);
3701 tem
= xmalloc (len
+ 1);
3702 memcpy (tem
, start
, len
);
3704 work
-> typevec
[work
-> ntypes
++] = tem
;
3708 /* Remember a K type class qualifier. */
3710 remember_Ktype (work
, start
, len
)
3711 struct work_stuff
*work
;
3717 if (work
-> numk
>= work
-> ksize
)
3719 if (work
-> ksize
== 0)
3723 = (char **) xmalloc (sizeof (char *) * work
-> ksize
);
3729 = (char **) xrealloc ((char *)work
-> ktypevec
,
3730 sizeof (char *) * work
-> ksize
);
3733 tem
= xmalloc (len
+ 1);
3734 memcpy (tem
, start
, len
);
3736 work
-> ktypevec
[work
-> numk
++] = tem
;
3739 /* Register a B code, and get an index for it. B codes are registered
3740 as they are seen, rather than as they are completed, so map<temp<char> >
3741 registers map<temp<char> > as B0, and temp<char> as B1 */
3744 register_Btype (work
)
3745 struct work_stuff
*work
;
3749 if (work
-> numb
>= work
-> bsize
)
3751 if (work
-> bsize
== 0)
3755 = (char **) xmalloc (sizeof (char *) * work
-> bsize
);
3761 = (char **) xrealloc ((char *)work
-> btypevec
,
3762 sizeof (char *) * work
-> bsize
);
3765 ret
= work
-> numb
++;
3766 work
-> btypevec
[ret
] = NULL
;
3770 /* Store a value into a previously registered B code type. */
3773 remember_Btype (work
, start
, len
, index
)
3774 struct work_stuff
*work
;
3780 tem
= xmalloc (len
+ 1);
3781 memcpy (tem
, start
, len
);
3783 work
-> btypevec
[index
] = tem
;
3786 /* Lose all the info related to B and K type codes. */
3788 forget_B_and_K_types (work
)
3789 struct work_stuff
*work
;
3793 while (work
-> numk
> 0)
3795 i
= --(work
-> numk
);
3796 if (work
-> ktypevec
[i
] != NULL
)
3798 free (work
-> ktypevec
[i
]);
3799 work
-> ktypevec
[i
] = NULL
;
3803 while (work
-> numb
> 0)
3805 i
= --(work
-> numb
);
3806 if (work
-> btypevec
[i
] != NULL
)
3808 free (work
-> btypevec
[i
]);
3809 work
-> btypevec
[i
] = NULL
;
3813 /* Forget the remembered types, but not the type vector itself. */
3817 struct work_stuff
*work
;
3821 while (work
-> ntypes
> 0)
3823 i
= --(work
-> ntypes
);
3824 if (work
-> typevec
[i
] != NULL
)
3826 free (work
-> typevec
[i
]);
3827 work
-> typevec
[i
] = NULL
;
3832 /* Process the argument list part of the signature, after any class spec
3833 has been consumed, as well as the first 'F' character (if any). For
3836 "__als__3fooRT0" => process "RT0"
3837 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3839 DECLP must be already initialised, usually non-empty. It won't be freed
3842 Note that g++ differs significantly from ARM and lucid style mangling
3843 with regards to references to previously seen types. For example, given
3844 the source fragment:
3848 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3851 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3852 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3854 g++ produces the names:
3859 while lcc (and presumably other ARM style compilers as well) produces:
3861 foo__FiR3fooT1T2T1T2
3862 __ct__3fooFiR3fooT1T2T1T2
3864 Note that g++ bases its type numbers starting at zero and counts all
3865 previously seen types, while lucid/ARM bases its type numbers starting
3866 at one and only considers types after it has seen the 'F' character
3867 indicating the start of the function args. For lucid/ARM style, we
3868 account for this difference by discarding any previously seen types when
3869 we see the 'F' character, and subtracting one from the type number
3875 demangle_args (work
, mangled
, declp
)
3876 struct work_stuff
*work
;
3877 const char **mangled
;
3887 if (PRINT_ARG_TYPES
)
3889 string_append (declp
, "(");
3890 if (**mangled
== '\0')
3892 string_append (declp
, "void");
3896 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
3897 || work
->nrepeats
> 0)
3899 if ((**mangled
== 'N') || (**mangled
== 'T'))
3901 temptype
= *(*mangled
)++;
3903 if (temptype
== 'N')
3905 if (!get_count (mangled
, &r
))
3914 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
3916 /* If we have 10 or more types we might have more than a 1 digit
3917 index so we'll have to consume the whole count here. This
3918 will lose if the next thing is a type name preceded by a
3919 count but it's impossible to demangle that case properly
3920 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3921 Pc, ...)" or "(..., type12, char *, ...)" */
3922 if ((t
= consume_count(mangled
)) <= 0)
3929 if (!get_count (mangled
, &t
))
3934 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
3938 /* Validate the type index. Protect against illegal indices from
3939 malformed type strings. */
3940 if ((t
< 0) || (t
>= work
-> ntypes
))
3944 while (work
->nrepeats
> 0 || --r
>= 0)
3946 tem
= work
-> typevec
[t
];
3947 if (need_comma
&& PRINT_ARG_TYPES
)
3949 string_append (declp
, ", ");
3951 if (!do_arg (work
, &tem
, &arg
))
3955 if (PRINT_ARG_TYPES
)
3957 string_appends (declp
, &arg
);
3959 string_delete (&arg
);
3965 if (need_comma
&& PRINT_ARG_TYPES
)
3966 string_append (declp
, ", ");
3967 if (!do_arg (work
, mangled
, &arg
))
3969 if (PRINT_ARG_TYPES
)
3970 string_appends (declp
, &arg
);
3971 string_delete (&arg
);
3976 if (**mangled
== 'e')
3979 if (PRINT_ARG_TYPES
)
3983 string_append (declp
, ",");
3985 string_append (declp
, "...");
3989 if (PRINT_ARG_TYPES
)
3991 string_append (declp
, ")");
3996 /* Like demangle_args, but for demangling the argument lists of function
3997 and method pointers or references, not top-level declarations. */
4000 demangle_nested_args (work
, mangled
, declp
)
4001 struct work_stuff
*work
;
4002 const char **mangled
;
4005 string
* saved_previous_argument
;
4009 /* The G++ name-mangling algorithm does not remember types on nested
4010 argument lists, unless -fsquangling is used, and in that case the
4011 type vector updated by remember_type is not used. So, we turn
4012 off remembering of types here. */
4013 ++work
->forgetting_types
;
4015 /* For the repeat codes used with -fsquangling, we must keep track of
4016 the last argument. */
4017 saved_previous_argument
= work
->previous_argument
;
4018 saved_nrepeats
= work
->nrepeats
;
4019 work
->previous_argument
= 0;
4022 /* Actually demangle the arguments. */
4023 result
= demangle_args (work
, mangled
, declp
);
4025 /* Restore the previous_argument field. */
4026 if (work
->previous_argument
)
4027 string_delete (work
->previous_argument
);
4028 work
->previous_argument
= saved_previous_argument
;
4029 --work
->forgetting_types
;
4030 work
->nrepeats
= saved_nrepeats
;
4036 demangle_function_name (work
, mangled
, declp
, scan
)
4037 struct work_stuff
*work
;
4038 const char **mangled
;
4046 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4047 string_need (declp
, 1);
4048 *(declp
-> p
) = '\0';
4050 /* Consume the function name, including the "__" separating the name
4051 from the signature. We are guaranteed that SCAN points to the
4054 (*mangled
) = scan
+ 2;
4055 /* We may be looking at an instantiation of a template function:
4056 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4057 following _F marks the start of the function arguments. Handle
4058 the template arguments first. */
4060 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4062 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4063 /* This leaves MANGLED pointing to the 'F' marking func args */
4066 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4069 /* See if we have an ARM style constructor or destructor operator.
4070 If so, then just record it, clear the decl, and return.
4071 We can't build the actual constructor/destructor decl until later,
4072 when we recover the class name from the signature. */
4074 if (strcmp (declp
-> b
, "__ct") == 0)
4076 work
-> constructor
+= 1;
4077 string_clear (declp
);
4080 else if (strcmp (declp
-> b
, "__dt") == 0)
4082 work
-> destructor
+= 1;
4083 string_clear (declp
);
4088 if (declp
->p
- declp
->b
>= 3
4089 && declp
->b
[0] == 'o'
4090 && declp
->b
[1] == 'p'
4091 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4093 /* see if it's an assignment expression */
4094 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4095 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4097 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4099 int len
= declp
->p
- declp
->b
- 10;
4100 if ((int) strlen (optable
[i
].in
) == len
4101 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4103 string_clear (declp
);
4104 string_append (declp
, "operator");
4105 string_append (declp
, optable
[i
].out
);
4106 string_append (declp
, "=");
4113 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4115 int len
= declp
->p
- declp
->b
- 3;
4116 if ((int) strlen (optable
[i
].in
) == len
4117 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4119 string_clear (declp
);
4120 string_append (declp
, "operator");
4121 string_append (declp
, optable
[i
].out
);
4127 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4128 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4130 /* type conversion operator */
4132 if (do_type (work
, &tem
, &type
))
4134 string_clear (declp
);
4135 string_append (declp
, "operator ");
4136 string_appends (declp
, &type
);
4137 string_delete (&type
);
4140 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4141 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4144 /* type conversion operator. */
4146 if (do_type (work
, &tem
, &type
))
4148 string_clear (declp
);
4149 string_append (declp
, "operator ");
4150 string_appends (declp
, &type
);
4151 string_delete (&type
);
4154 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4155 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
4156 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
4158 if (declp
->b
[4] == '\0')
4161 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4163 if (strlen (optable
[i
].in
) == 2
4164 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4166 string_clear (declp
);
4167 string_append (declp
, "operator");
4168 string_append (declp
, optable
[i
].out
);
4175 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4178 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4180 if (strlen (optable
[i
].in
) == 3
4181 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4183 string_clear (declp
);
4184 string_append (declp
, "operator");
4185 string_append (declp
, optable
[i
].out
);
4194 /* a mini string-handling package */
4209 s
->p
= s
->b
= xmalloc (n
);
4212 else if (s
->e
- s
->p
< n
)
4217 s
->b
= xrealloc (s
->b
, n
);
4230 s
->b
= s
->e
= s
->p
= NULL
;
4238 s
->b
= s
->p
= s
->e
= NULL
;
4254 return (s
->b
== s
->p
);
4260 string_append (p
, s
)
4265 if (s
== NULL
|| *s
== '\0')
4269 memcpy (p
->p
, s
, n
);
4274 string_appends (p
, s
)
4283 memcpy (p
->p
, s
->b
, n
);
4289 string_appendn (p
, s
, n
)
4297 memcpy (p
->p
, s
, n
);
4303 string_prepend (p
, s
)
4307 if (s
!= NULL
&& *s
!= '\0')
4309 string_prependn (p
, s
, strlen (s
));
4314 string_prepends (p
, s
)
4319 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4324 string_prependn (p
, s
, n
)
4334 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4338 memcpy (p
->b
, s
, n
);
4343 /* To generate a standalone demangler program for testing purposes,
4344 just compile and link this file with -DMAIN and libiberty.a. When
4345 run, it demangles each command line arg, or each stdin string, and
4346 prints the result on stdout. */
4352 static const char *program_name
;
4353 static const char *program_version
= VERSION
;
4354 static int flags
= DMGL_PARAMS
| DMGL_ANSI
;
4356 static void demangle_it
PARAMS ((char *));
4357 static void usage
PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN
;
4358 static void fatal
PARAMS ((const char *)) ATTRIBUTE_NORETURN
;
4361 demangle_it (mangled_name
)
4366 result
= cplus_demangle (mangled_name
, flags
);
4369 printf ("%s\n", mangled_name
);
4373 printf ("%s\n", result
);
4379 usage (stream
, status
)
4384 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4385 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4386 [--help] [--version] [arg...]\n",
4391 #define MBUF_SIZE 32767
4392 char mbuffer
[MBUF_SIZE
];
4394 /* Defined in the automatically-generated underscore.c. */
4395 extern int prepends_underscore
;
4397 int strip_underscore
= 0;
4399 static struct option long_options
[] = {
4400 {"strip-underscores", no_argument
, 0, '_'},
4401 {"format", required_argument
, 0, 's'},
4402 {"help", no_argument
, 0, 'h'},
4403 {"java", no_argument
, 0, 'j'},
4404 {"no-strip-underscores", no_argument
, 0, 'n'},
4405 {"version", no_argument
, 0, 'v'},
4406 {0, no_argument
, 0, 0}
4409 /* More 'friendly' abort that prints the line and file.
4410 config.h can #define abort fancy_abort if you like that sort of thing. */
4415 fatal ("Internal gcc abort.");
4419 /* Return the string of non-alnum characters that may occur
4420 as a valid symbol component, in the standard assembler symbol
4424 standard_symbol_characters ()
4430 /* Return the string of non-alnum characters that may occur
4431 as a valid symbol name component in an HP object file.
4433 Note that, since HP's compiler generates object code straight from
4434 C++ source, without going through an assembler, its mangled
4435 identifiers can use all sorts of characters that no assembler would
4436 tolerate, so the alphabet this function creates is a little odd.
4437 Here are some sample mangled identifiers offered by HP:
4439 typeid*__XT24AddressIndExpClassMember_
4440 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4441 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4443 This still seems really weird to me, since nowhere else in this
4444 file is there anything to recognize curly brackets, parens, etc.
4445 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4446 this is right, but I still strongly suspect that there's a
4447 misunderstanding here.
4449 If we decide it's better for c++filt to use HP's assembler syntax
4450 to scrape identifiers out of its input, here's the definition of
4451 the symbol name syntax from the HP assembler manual:
4453 Symbols are composed of uppercase and lowercase letters, decimal
4454 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4455 underscore (_). A symbol can begin with a letter, digit underscore or
4456 dollar sign. If a symbol begins with a digit, it must contain a
4457 non-digit character.
4461 hp_symbol_characters ()
4463 return "_$.<>#,*&[]:(){}";
4467 extern int main
PARAMS ((int, char **));
4476 const char *valid_symbols
;
4478 program_name
= argv
[0];
4480 strip_underscore
= prepends_underscore
;
4482 while ((c
= getopt_long (argc
, argv
, "_ns:j", long_options
, (int *) 0)) != EOF
)
4492 strip_underscore
= 0;
4495 printf ("GNU %s (C++ demangler), version %s\n", program_name
, program_version
);
4498 strip_underscore
= 1;
4504 if (strcmp (optarg
, "gnu") == 0)
4506 current_demangling_style
= gnu_demangling
;
4508 else if (strcmp (optarg
, "lucid") == 0)
4510 current_demangling_style
= lucid_demangling
;
4512 else if (strcmp (optarg
, "arm") == 0)
4514 current_demangling_style
= arm_demangling
;
4516 else if (strcmp (optarg
, "hp") == 0)
4518 current_demangling_style
= hp_demangling
;
4520 else if (strcmp (optarg
, "edg") == 0)
4522 current_demangling_style
= edg_demangling
;
4526 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
4527 program_name
, optarg
);
4536 for ( ; optind
< argc
; optind
++)
4538 demangle_it (argv
[optind
]);
4543 switch (current_demangling_style
)
4545 case gnu_demangling
:
4546 case lucid_demangling
:
4547 case arm_demangling
:
4548 case edg_demangling
:
4549 valid_symbols
= standard_symbol_characters ();
4552 valid_symbols
= hp_symbol_characters ();
4555 /* Folks should explicitly indicate the appropriate alphabet for
4556 each demangling. Providing a default would allow the
4557 question to go unconsidered. */
4565 /* Try to read a label. */
4566 while (c
!= EOF
&& (isalnum (c
) || strchr (valid_symbols
, c
)))
4568 if (i
>= MBUF_SIZE
-1)
4577 if (mbuffer
[0] == '.')
4579 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
4587 result
= cplus_demangle (mbuffer
+ skip_first
, flags
);
4590 if (mbuffer
[0] == '.')
4592 fputs (result
, stdout
);
4596 fputs (mbuffer
, stdout
);
4613 fprintf (stderr
, "%s: %s\n", program_name
, str
);
4621 register PTR value
= (PTR
) malloc (size
);
4623 fatal ("virtual memory exhausted");
4628 xrealloc (ptr
, size
)
4632 register PTR value
= (PTR
) realloc (ptr
, size
);
4634 fatal ("virtual memory exhausted");