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 static const char *mystrstr
PARAMS ((const char *, const char *));
60 register const char *p
= s1
;
61 register int len
= strlen (s2
);
63 for (; (p
= strchr (p
, *s2
)) != 0; p
++)
65 if (strncmp (p
, s2
, len
) == 0)
73 /* In order to allow a single demangler executable to demangle strings
74 using various common values of CPLUS_MARKER, as well as any specific
75 one set at compile time, we maintain a string containing all the
76 commonly used ones, and check to see if the marker we are looking for
77 is in that string. CPLUS_MARKER is usually '$' on systems where the
78 assembler can deal with that. Where the assembler can't, it's usually
79 '.' (but on many systems '.' is used for other things). We put the
80 current defined CPLUS_MARKER first (which defaults to '$'), followed
81 by the next most common value, followed by an explicit '$' in case
82 the value of CPLUS_MARKER is not '$'.
84 We could avoid this if we could just get g++ to tell us what the actual
85 cplus marker character is as part of the debug information, perhaps by
86 ensuring that it is the character that terminates the gcc<n>_compiled
87 marker symbol (FIXME). */
89 #if !defined (CPLUS_MARKER)
90 #define CPLUS_MARKER '$'
93 enum demangling_styles current_demangling_style
= gnu_demangling
;
95 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
97 static char char_str
[2] = { '\000', '\000' };
100 set_cplus_marker_for_demangling (ch
)
103 cplus_markers
[0] = ch
;
106 typedef struct string
/* Beware: these aren't required to be */
107 { /* '\0' terminated. */
108 char *b
; /* pointer to start of string */
109 char *p
; /* pointer after last character */
110 char *e
; /* pointer after end of allocated space */
113 /* Stuff that is shared between sub-routines.
114 Using a shared structure allows cplus_demangle to be reentrant. */
130 int static_type
; /* A static member function */
131 int temp_start
; /* index in demangled to start of template args */
132 int type_quals
; /* The type qualifiers. */
133 int dllimported
; /* Symbol imported from a PE DLL */
134 char **tmpl_argvec
; /* Template function arguments. */
135 int ntmpl_args
; /* The number of template function arguments. */
136 int forgetting_types
; /* Nonzero if we are not remembering the types
138 string
* previous_argument
; /* The last function argument demangled. */
139 int nrepeats
; /* The number of times to repeat the previous
143 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
144 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
146 static const struct optable
152 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
153 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
154 {"new", " new", 0}, /* old (1.91, and 1.x) */
155 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
156 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
157 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
158 {"as", "=", DMGL_ANSI
}, /* ansi */
159 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
160 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
161 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
162 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
163 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
164 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
165 {"plus", "+", 0}, /* old */
166 {"pl", "+", DMGL_ANSI
}, /* ansi */
167 {"apl", "+=", DMGL_ANSI
}, /* ansi */
168 {"minus", "-", 0}, /* old */
169 {"mi", "-", DMGL_ANSI
}, /* ansi */
170 {"ami", "-=", DMGL_ANSI
}, /* ansi */
171 {"mult", "*", 0}, /* old */
172 {"ml", "*", DMGL_ANSI
}, /* ansi */
173 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
174 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
175 {"convert", "+", 0}, /* old (unary +) */
176 {"negate", "-", 0}, /* old (unary -) */
177 {"trunc_mod", "%", 0}, /* old */
178 {"md", "%", DMGL_ANSI
}, /* ansi */
179 {"amd", "%=", DMGL_ANSI
}, /* ansi */
180 {"trunc_div", "/", 0}, /* old */
181 {"dv", "/", DMGL_ANSI
}, /* ansi */
182 {"adv", "/=", DMGL_ANSI
}, /* ansi */
183 {"truth_andif", "&&", 0}, /* old */
184 {"aa", "&&", DMGL_ANSI
}, /* ansi */
185 {"truth_orif", "||", 0}, /* old */
186 {"oo", "||", DMGL_ANSI
}, /* ansi */
187 {"truth_not", "!", 0}, /* old */
188 {"nt", "!", DMGL_ANSI
}, /* ansi */
189 {"postincrement","++", 0}, /* old */
190 {"pp", "++", DMGL_ANSI
}, /* ansi */
191 {"postdecrement","--", 0}, /* old */
192 {"mm", "--", DMGL_ANSI
}, /* ansi */
193 {"bit_ior", "|", 0}, /* old */
194 {"or", "|", DMGL_ANSI
}, /* ansi */
195 {"aor", "|=", DMGL_ANSI
}, /* ansi */
196 {"bit_xor", "^", 0}, /* old */
197 {"er", "^", DMGL_ANSI
}, /* ansi */
198 {"aer", "^=", DMGL_ANSI
}, /* ansi */
199 {"bit_and", "&", 0}, /* old */
200 {"ad", "&", DMGL_ANSI
}, /* ansi */
201 {"aad", "&=", DMGL_ANSI
}, /* ansi */
202 {"bit_not", "~", 0}, /* old */
203 {"co", "~", DMGL_ANSI
}, /* ansi */
204 {"call", "()", 0}, /* old */
205 {"cl", "()", DMGL_ANSI
}, /* ansi */
206 {"alshift", "<<", 0}, /* old */
207 {"ls", "<<", DMGL_ANSI
}, /* ansi */
208 {"als", "<<=", DMGL_ANSI
}, /* ansi */
209 {"arshift", ">>", 0}, /* old */
210 {"rs", ">>", DMGL_ANSI
}, /* ansi */
211 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
212 {"component", "->", 0}, /* old */
213 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
214 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
215 {"indirect", "*", 0}, /* old */
216 {"method_call", "->()", 0}, /* old */
217 {"addr", "&", 0}, /* old (unary &) */
218 {"array", "[]", 0}, /* old */
219 {"vc", "[]", DMGL_ANSI
}, /* ansi */
220 {"compound", ", ", 0}, /* old */
221 {"cm", ", ", DMGL_ANSI
}, /* ansi */
222 {"cond", "?:", 0}, /* old */
223 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
224 {"max", ">?", 0}, /* old */
225 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
226 {"min", "<?", 0}, /* old */
227 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
228 {"nop", "", 0}, /* old (for operator=) */
229 {"rm", "->*", DMGL_ANSI
}, /* ansi */
230 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
233 /* These values are used to indicate the various type varieties.
234 They are all non-zero so that they can be used as `success'
236 typedef enum type_kind_t
247 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
248 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
249 string_prepend(str, " ");}
250 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
251 string_append(str, " ");}
252 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
254 /* The scope separator appropriate for the language being demangled. */
256 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
258 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
259 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
261 /* Prototypes for local functions */
264 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
267 squangle_mop_up
PARAMS ((struct work_stuff
*));
271 demangle_method_args
PARAMS ((struct work_stuff
*, const char **, string
*));
275 internal_cplus_demangle
PARAMS ((struct work_stuff
*, const char *));
278 demangle_template_template_parm
PARAMS ((struct work_stuff
*work
,
279 const char **, string
*));
282 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*,
283 string
*, int, int));
286 arm_pt
PARAMS ((struct work_stuff
*, const char *, int, const char **,
290 demangle_class_name
PARAMS ((struct work_stuff
*, const char **, string
*));
293 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
297 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
300 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
303 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
306 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
309 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
312 arm_special
PARAMS ((const char **, string
*));
315 string_need
PARAMS ((string
*, int));
318 string_delete
PARAMS ((string
*));
321 string_init
PARAMS ((string
*));
324 string_clear
PARAMS ((string
*));
328 string_empty
PARAMS ((string
*));
332 string_append
PARAMS ((string
*, const char *));
335 string_appends
PARAMS ((string
*, string
*));
338 string_appendn
PARAMS ((string
*, const char *, int));
341 string_prepend
PARAMS ((string
*, const char *));
344 string_prependn
PARAMS ((string
*, const char *, int));
347 get_count
PARAMS ((const char **, int *));
350 consume_count
PARAMS ((const char **));
353 consume_count_with_underscores
PARAMS ((const char**));
356 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
359 demangle_nested_args
PARAMS ((struct work_stuff
*, const char**, string
*));
362 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
365 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
368 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
372 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
375 remember_Btype
PARAMS ((struct work_stuff
*, const char *, int, int));
378 register_Btype
PARAMS ((struct work_stuff
*));
381 remember_Ktype
PARAMS ((struct work_stuff
*, const char *, int));
384 forget_types
PARAMS ((struct work_stuff
*));
387 forget_B_and_K_types
PARAMS ((struct work_stuff
*));
390 string_prepends
PARAMS ((string
*, string
*));
393 demangle_template_value_parm
PARAMS ((struct work_stuff
*, const char**,
394 string
*, type_kind_t
));
397 do_hpacc_template_const_value
PARAMS ((struct work_stuff
*, const char **, string
*));
400 do_hpacc_template_literal
PARAMS ((struct work_stuff
*, const char **, string
*));
403 snarf_numeric_literal
PARAMS ((const char **, string
*));
405 /* There is a TYPE_QUAL value for each type qualifier. They can be
406 combined by bitwise-or to form the complete set of qualifiers for a
409 #define TYPE_UNQUALIFIED 0x0
410 #define TYPE_QUAL_CONST 0x1
411 #define TYPE_QUAL_VOLATILE 0x2
412 #define TYPE_QUAL_RESTRICT 0x4
415 code_for_qualifier
PARAMS ((int));
418 qualifier_string
PARAMS ((int));
421 demangle_qualifier
PARAMS ((int));
423 /* Translate count to integer, consuming tokens in the process.
424 Conversion terminates on the first non-digit character.
426 Trying to consume something that isn't a count results in no
427 consumption of input and a return of -1.
429 Overflow consumes the rest of the digits, and returns -1. */
437 if (! isdigit ((unsigned char)**type
))
440 while (isdigit ((unsigned char)**type
))
444 /* Check for overflow.
445 We assume that count is represented using two's-complement;
446 no power of two is divisible by ten, so if an overflow occurs
447 when multiplying by ten, the result will not be a multiple of
449 if ((count
% 10) != 0)
451 while (isdigit ((unsigned char) **type
))
456 count
+= **type
- '0';
464 /* Like consume_count, but for counts that are preceded and followed
465 by '_' if they are greater than 10. Also, -1 is returned for
466 failure, since 0 can be a valid value. */
469 consume_count_with_underscores (mangled
)
470 const char **mangled
;
474 if (**mangled
== '_')
477 if (!isdigit ((unsigned char)**mangled
))
480 idx
= consume_count (mangled
);
481 if (**mangled
!= '_')
482 /* The trailing underscore was missing. */
489 if (**mangled
< '0' || **mangled
> '9')
492 idx
= **mangled
- '0';
499 /* C is the code for a type-qualifier. Return the TYPE_QUAL
500 corresponding to this qualifier. */
503 code_for_qualifier (c
)
509 return TYPE_QUAL_CONST
;
512 return TYPE_QUAL_VOLATILE
;
515 return TYPE_QUAL_RESTRICT
;
521 /* C was an invalid qualifier. */
525 /* Return the string corresponding to the qualifiers given by
529 qualifier_string (type_quals
)
534 case TYPE_UNQUALIFIED
:
537 case TYPE_QUAL_CONST
:
540 case TYPE_QUAL_VOLATILE
:
543 case TYPE_QUAL_RESTRICT
:
546 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
547 return "const volatile";
549 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
550 return "const __restrict";
552 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
553 return "volatile __restrict";
555 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
556 return "const volatile __restrict";
562 /* TYPE_QUALS was an invalid qualifier set. */
566 /* C is the code for a type-qualifier. Return the string
567 corresponding to this qualifier. This function should only be
568 called with a valid qualifier code. */
571 demangle_qualifier (c
)
574 return qualifier_string (code_for_qualifier (c
));
578 cplus_demangle_opname (opname
, result
, options
)
585 struct work_stuff work
[1];
588 len
= strlen(opname
);
591 memset ((char *) work
, 0, sizeof (work
));
592 work
->options
= options
;
594 if (opname
[0] == '_' && opname
[1] == '_'
595 && opname
[2] == 'o' && opname
[3] == 'p')
598 /* type conversion operator. */
600 if (do_type (work
, &tem
, &type
))
602 strcat (result
, "operator ");
603 strncat (result
, type
.b
, type
.p
- type
.b
);
604 string_delete (&type
);
608 else if (opname
[0] == '_' && opname
[1] == '_'
609 && opname
[2] >= 'a' && opname
[2] <= 'z'
610 && opname
[3] >= 'a' && opname
[3] <= 'z')
612 if (opname
[4] == '\0')
616 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
618 if (strlen (optable
[i
].in
) == 2
619 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
621 strcat (result
, "operator");
622 strcat (result
, optable
[i
].out
);
630 if (opname
[2] == 'a' && opname
[5] == '\0')
634 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
636 if (strlen (optable
[i
].in
) == 3
637 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
639 strcat (result
, "operator");
640 strcat (result
, optable
[i
].out
);
651 && strchr (cplus_markers
, opname
[2]) != NULL
)
653 /* see if it's an assignment expression */
654 if (len
>= 10 /* op$assign_ */
655 && memcmp (opname
+ 3, "assign_", 7) == 0)
658 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
661 if ((int) strlen (optable
[i
].in
) == len1
662 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
664 strcat (result
, "operator");
665 strcat (result
, optable
[i
].out
);
666 strcat (result
, "=");
675 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
678 if ((int) strlen (optable
[i
].in
) == len1
679 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
681 strcat (result
, "operator");
682 strcat (result
, optable
[i
].out
);
689 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
690 && strchr (cplus_markers
, opname
[4]) != NULL
)
692 /* type conversion operator */
694 if (do_type (work
, &tem
, &type
))
696 strcat (result
, "operator ");
697 strncat (result
, type
.b
, type
.p
- type
.b
);
698 string_delete (&type
);
702 squangle_mop_up (work
);
706 /* Takes operator name as e.g. "++" and returns mangled
707 operator name (e.g. "postincrement_expr"), or NULL if not found.
709 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
710 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
713 cplus_mangle_opname (opname
, options
)
720 len
= strlen (opname
);
721 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
723 if ((int) strlen (optable
[i
].out
) == len
724 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
725 && memcmp (optable
[i
].out
, opname
, len
) == 0)
726 return optable
[i
].in
;
731 /* char *cplus_demangle (const char *mangled, int options)
733 If MANGLED is a mangled function name produced by GNU C++, then
734 a pointer to a malloced string giving a C++ representation
735 of the name will be returned; otherwise NULL will be returned.
736 It is the caller's responsibility to free the string which
739 The OPTIONS arg may contain one or more of the following bits:
741 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
743 DMGL_PARAMS Function parameters are included.
747 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
748 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
749 cplus_demangle ("foo__1Ai", 0) => "A::foo"
751 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
752 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
753 cplus_demangle ("foo__1Afe", 0) => "A::foo"
755 Note that any leading underscores, or other such characters prepended by
756 the compilation system, are presumed to have already been stripped from
760 cplus_demangle (mangled
, options
)
765 struct work_stuff work
[1];
766 memset ((char *) work
, 0, sizeof (work
));
767 work
-> options
= options
;
768 if ((work
-> options
& DMGL_STYLE_MASK
) == 0)
769 work
-> options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
771 ret
= internal_cplus_demangle (work
, mangled
);
772 squangle_mop_up (work
);
777 /* This function performs most of what cplus_demangle use to do, but
778 to be able to demangle a name with a B, K or n code, we need to
779 have a longer term memory of what types have been seen. The original
780 now intializes and cleans up the squangle code info, while internal
781 calls go directly to this routine to avoid resetting that info. */
784 internal_cplus_demangle (work
, mangled
)
785 struct work_stuff
*work
;
791 char *demangled
= NULL
;
793 s1
= work
->constructor
;
794 s2
= work
->destructor
;
795 s3
= work
->static_type
;
796 s4
= work
->type_quals
;
797 work
->constructor
= work
->destructor
= 0;
798 work
->type_quals
= TYPE_UNQUALIFIED
;
799 work
->dllimported
= 0;
801 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
805 /* First check to see if gnu style demangling is active and if the
806 string to be demangled contains a CPLUS_MARKER. If so, attempt to
807 recognize one of the gnu special forms rather than looking for a
808 standard prefix. In particular, don't worry about whether there
809 is a "__" string in the mangled string. Consider "_$_5__foo" for
812 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
814 success
= gnu_special (work
, &mangled
, &decl
);
818 success
= demangle_prefix (work
, &mangled
, &decl
);
820 if (success
&& (*mangled
!= '\0'))
822 success
= demangle_signature (work
, &mangled
, &decl
);
824 if (work
->constructor
== 2)
826 string_prepend (&decl
, "global constructors keyed to ");
827 work
->constructor
= 0;
829 else if (work
->destructor
== 2)
831 string_prepend (&decl
, "global destructors keyed to ");
832 work
->destructor
= 0;
834 else if (work
->dllimported
== 1)
836 string_prepend (&decl
, "import stub for ");
837 work
->dllimported
= 0;
839 demangled
= mop_up (work
, &decl
, success
);
841 work
->constructor
= s1
;
842 work
->destructor
= s2
;
843 work
->static_type
= s3
;
844 work
->type_quals
= s4
;
849 /* Clear out and squangling related storage */
851 squangle_mop_up (work
)
852 struct work_stuff
*work
;
854 /* clean up the B and K type mangling types. */
855 forget_B_and_K_types (work
);
856 if (work
-> btypevec
!= NULL
)
858 free ((char *) work
-> btypevec
);
860 if (work
-> ktypevec
!= NULL
)
862 free ((char *) work
-> ktypevec
);
866 /* Clear out any mangled storage */
869 mop_up (work
, declp
, success
)
870 struct work_stuff
*work
;
874 char *demangled
= NULL
;
876 /* Discard the remembered types, if any. */
879 if (work
-> typevec
!= NULL
)
881 free ((char *) work
-> typevec
);
882 work
-> typevec
= NULL
;
883 work
-> typevec_size
= 0;
885 if (work
->tmpl_argvec
)
889 for (i
= 0; i
< work
->ntmpl_args
; i
++)
890 if (work
->tmpl_argvec
[i
])
891 free ((char*) work
->tmpl_argvec
[i
]);
893 free ((char*) work
->tmpl_argvec
);
894 work
->tmpl_argvec
= NULL
;
896 if (work
->previous_argument
)
898 string_delete (work
->previous_argument
);
899 free ((char*) work
->previous_argument
);
900 work
->previous_argument
= NULL
;
903 /* If demangling was successful, ensure that the demangled string is null
904 terminated and return it. Otherwise, free the demangling decl. */
908 string_delete (declp
);
912 string_appendn (declp
, "", 1);
913 demangled
= declp
-> b
;
922 demangle_signature -- demangle the signature part of a mangled name
927 demangle_signature (struct work_stuff *work, const char **mangled,
932 Consume and demangle the signature portion of the mangled name.
934 DECLP is the string where demangled output is being built. At
935 entry it contains the demangled root name from the mangled name
936 prefix. I.E. either a demangled operator name or the root function
937 name. In some special cases, it may contain nothing.
939 *MANGLED points to the current unconsumed location in the mangled
940 name. As tokens are consumed and demangling is performed, the
941 pointer is updated to continuously point at the next token to
944 Demangling GNU style mangled names is nasty because there is no
945 explicit token that marks the start of the outermost function
949 demangle_signature (work
, mangled
, declp
)
950 struct work_stuff
*work
;
951 const char **mangled
;
957 int expect_return_type
= 0;
958 const char *oldmangled
= NULL
;
962 while (success
&& (**mangled
!= '\0'))
967 oldmangled
= *mangled
;
968 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
970 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
971 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
977 oldmangled
= *mangled
;
978 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
979 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
987 /* Static member function */
988 if (oldmangled
== NULL
)
990 oldmangled
= *mangled
;
993 work
-> static_type
= 1;
999 work
->type_quals
|= code_for_qualifier (**mangled
);
1001 /* a qualified member function */
1002 if (oldmangled
== NULL
)
1003 oldmangled
= *mangled
;
1008 /* Local class name follows after "Lnnn_" */
1011 while (**mangled
&& (**mangled
!= '_'))
1022 case '0': case '1': case '2': case '3': case '4':
1023 case '5': case '6': case '7': case '8': case '9':
1024 if (oldmangled
== NULL
)
1026 oldmangled
= *mangled
;
1028 work
->temp_start
= -1; /* uppermost call to demangle_class */
1029 success
= demangle_class (work
, mangled
, declp
);
1032 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1034 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1036 /* EDG and others will have the "F", so we let the loop cycle
1037 if we are looking at one. */
1038 if (**mangled
!= 'F')
1047 success
= do_type (work
, mangled
, &s
);
1050 string_append (&s
, SCOPE_STRING (work
));
1051 string_prepends (declp
, &s
);
1060 /* ARM/HP style demangling includes a specific 'F' character after
1061 the class name. For GNU style, it is just implied. So we can
1062 safely just consume any 'F' at this point and be compatible
1063 with either style. */
1069 /* For lucid/ARM/HP style we have to forget any types we might
1070 have remembered up to this point, since they were not argument
1071 types. GNU style considers all types seen as available for
1072 back references. See comment in demangle_args() */
1074 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1076 forget_types (work
);
1078 success
= demangle_args (work
, mangled
, declp
);
1079 /* After picking off the function args, we expect to either
1080 find the function return type (preceded by an '_') or the
1081 end of the string. */
1082 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1085 /* At this level, we do not care about the return type. */
1086 success
= do_type (work
, mangled
, &tname
);
1087 string_delete (&tname
);
1094 string_init(&trawname
);
1095 string_init(&tname
);
1096 if (oldmangled
== NULL
)
1098 oldmangled
= *mangled
;
1100 success
= demangle_template (work
, mangled
, &tname
,
1104 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1106 string_append (&tname
, SCOPE_STRING (work
));
1108 string_prepends(declp
, &tname
);
1109 if (work
-> destructor
& 1)
1111 string_prepend (&trawname
, "~");
1112 string_appends (declp
, &trawname
);
1113 work
->destructor
-= 1;
1115 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1117 string_appends (declp
, &trawname
);
1118 work
->constructor
-= 1;
1120 string_delete(&trawname
);
1121 string_delete(&tname
);
1127 if (GNU_DEMANGLING
&& expect_return_type
)
1129 /* Read the return type. */
1131 string_init (&return_type
);
1134 success
= do_type (work
, mangled
, &return_type
);
1135 APPEND_BLANK (&return_type
);
1137 string_prepends (declp
, &return_type
);
1138 string_delete (&return_type
);
1142 /* At the outermost level, we cannot have a return type specified,
1143 so if we run into another '_' at this point we are dealing with
1144 a mangled name that is either bogus, or has been mangled by
1145 some algorithm we don't know how to deal with. So just
1146 reject the entire demangling. */
1147 /* However, "_nnn" is an expected suffix for alternate entry point
1148 numbered nnn for a function, with HP aCC, so skip over that
1149 without reporting failure. pai/1997-09-04 */
1153 while (**mangled
&& isdigit ((unsigned char)**mangled
))
1163 /* A G++ template function. Read the template arguments. */
1164 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1166 if (!(work
->constructor
& 1))
1167 expect_return_type
= 1;
1176 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1178 /* Assume we have stumbled onto the first outermost function
1179 argument token, and start processing args. */
1181 success
= demangle_args (work
, mangled
, declp
);
1185 /* Non-GNU demanglers use a specific token to mark the start
1186 of the outermost function argument tokens. Typically 'F',
1187 for ARM/HP-demangling, for example. So if we find something
1188 we are not prepared for, it must be an error. */
1194 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1197 if (success
&& expect_func
)
1200 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1202 forget_types (work
);
1204 success
= demangle_args (work
, mangled
, declp
);
1205 /* Since template include the mangling of their return types,
1206 we must set expect_func to 0 so that we don't try do
1207 demangle more arguments the next time we get here. */
1212 if (success
&& !func_done
)
1214 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1216 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1217 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1218 first case, and need to ensure that the '(void)' gets added to
1219 the current declp. Note that with ARM/HP, the first case
1220 represents the name of a static data member 'foo::bar',
1221 which is in the current declp, so we leave it alone. */
1222 success
= demangle_args (work
, mangled
, declp
);
1225 if (success
&& PRINT_ARG_TYPES
)
1227 if (work
->static_type
)
1228 string_append (declp
, " static");
1229 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1231 APPEND_BLANK (declp
);
1232 string_append (declp
, qualifier_string (work
->type_quals
));
1242 demangle_method_args (work
, mangled
, declp
)
1243 struct work_stuff
*work
;
1244 const char **mangled
;
1249 if (work
-> static_type
)
1251 string_append (declp
, *mangled
+ 1);
1252 *mangled
+= strlen (*mangled
);
1257 success
= demangle_args (work
, mangled
, declp
);
1265 demangle_template_template_parm (work
, mangled
, tname
)
1266 struct work_stuff
*work
;
1267 const char **mangled
;
1276 string_append (tname
, "template <");
1277 /* get size of template parameter list */
1278 if (get_count (mangled
, &r
))
1280 for (i
= 0; i
< r
; i
++)
1284 string_append (tname
, ", ");
1287 /* Z for type parameters */
1288 if (**mangled
== 'Z')
1291 string_append (tname
, "class");
1293 /* z for template parameters */
1294 else if (**mangled
== 'z')
1298 demangle_template_template_parm (work
, mangled
, tname
);
1306 /* temp is initialized in do_type */
1307 success
= do_type (work
, mangled
, &temp
);
1310 string_appends (tname
, &temp
);
1312 string_delete(&temp
);
1322 if (tname
->p
[-1] == '>')
1323 string_append (tname
, " ");
1324 string_append (tname
, "> class");
1329 demangle_integral_value (work
, mangled
, s
)
1330 struct work_stuff
*work
;
1331 const char** mangled
;
1336 if (**mangled
== 'E')
1338 int need_operator
= 0;
1341 string_appendn (s
, "(", 1);
1343 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1352 len
= strlen (*mangled
);
1355 i
< sizeof (optable
) / sizeof (optable
[0]);
1358 size_t l
= strlen (optable
[i
].in
);
1361 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1363 string_appendn (s
, " ", 1);
1364 string_append (s
, optable
[i
].out
);
1365 string_appendn (s
, " ", 1);
1378 success
= demangle_template_value_parm (work
, mangled
, s
,
1382 if (**mangled
!= 'W')
1386 string_appendn (s
, ")", 1);
1390 else if (**mangled
== 'Q' || **mangled
== 'K')
1391 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1396 if (**mangled
== 'm')
1398 string_appendn (s
, "-", 1);
1401 while (isdigit ((unsigned char)**mangled
))
1403 string_appendn (s
, *mangled
, 1);
1413 demangle_template_value_parm (work
, mangled
, s
, tk
)
1414 struct work_stuff
*work
;
1415 const char **mangled
;
1421 if (**mangled
== 'Y')
1423 /* The next argument is a template parameter. */
1427 idx
= consume_count_with_underscores (mangled
);
1429 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1430 || consume_count_with_underscores (mangled
) == -1)
1432 if (work
->tmpl_argvec
)
1433 string_append (s
, work
->tmpl_argvec
[idx
]);
1437 sprintf(buf
, "T%d", idx
);
1438 string_append (s
, buf
);
1441 else if (tk
== tk_integral
)
1442 success
= demangle_integral_value (work
, mangled
, s
);
1443 else if (tk
== tk_char
)
1447 if (**mangled
== 'm')
1449 string_appendn (s
, "-", 1);
1452 string_appendn (s
, "'", 1);
1453 val
= consume_count(mangled
);
1460 string_appendn (s
, &tmp
[0], 1);
1461 string_appendn (s
, "'", 1);
1464 else if (tk
== tk_bool
)
1466 int val
= consume_count (mangled
);
1468 string_appendn (s
, "false", 5);
1470 string_appendn (s
, "true", 4);
1474 else if (tk
== tk_real
)
1476 if (**mangled
== 'm')
1478 string_appendn (s
, "-", 1);
1481 while (isdigit ((unsigned char)**mangled
))
1483 string_appendn (s
, *mangled
, 1);
1486 if (**mangled
== '.') /* fraction */
1488 string_appendn (s
, ".", 1);
1490 while (isdigit ((unsigned char)**mangled
))
1492 string_appendn (s
, *mangled
, 1);
1496 if (**mangled
== 'e') /* exponent */
1498 string_appendn (s
, "e", 1);
1500 while (isdigit ((unsigned char)**mangled
))
1502 string_appendn (s
, *mangled
, 1);
1507 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1509 int symbol_len
= consume_count (mangled
);
1510 if (symbol_len
== -1)
1512 if (symbol_len
== 0)
1513 string_appendn (s
, "0", 1);
1516 char *p
= xmalloc (symbol_len
+ 1), *q
;
1517 strncpy (p
, *mangled
, symbol_len
);
1518 p
[symbol_len
] = '\0';
1519 /* We use cplus_demangle here, rather than
1520 internal_cplus_demangle, because the name of the entity
1521 mangled here does not make use of any of the squangling
1522 or type-code information we have built up thus far; it is
1523 mangled independently. */
1524 q
= cplus_demangle (p
, work
->options
);
1525 if (tk
== tk_pointer
)
1526 string_appendn (s
, "&", 1);
1527 /* FIXME: Pointer-to-member constants should get a
1528 qualifying class name here. */
1531 string_append (s
, q
);
1535 string_append (s
, p
);
1538 *mangled
+= symbol_len
;
1544 /* Demangle the template name in MANGLED. The full name of the
1545 template (e.g., S<int>) is placed in TNAME. The name without the
1546 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1547 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1548 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1549 the tmeplate is remembered in the list of back-referenceable
1553 demangle_template (work
, mangled
, tname
, trawname
, is_type
, remember
)
1554 struct work_stuff
*work
;
1555 const char **mangled
;
1566 int is_java_array
= 0;
1574 bindex
= register_Btype (work
);
1576 /* get template name */
1577 if (**mangled
== 'z')
1583 idx
= consume_count_with_underscores (mangled
);
1585 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1586 || consume_count_with_underscores (mangled
) == -1)
1589 if (work
->tmpl_argvec
)
1591 string_append (tname
, work
->tmpl_argvec
[idx
]);
1593 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1598 sprintf(buf
, "T%d", idx
);
1599 string_append (tname
, buf
);
1601 string_append (trawname
, buf
);
1606 if ((r
= consume_count (mangled
)) <= 0
1607 || (int) strlen (*mangled
) < r
)
1611 is_java_array
= (work
-> options
& DMGL_JAVA
)
1612 && strncmp (*mangled
, "JArray1Z", 8) == 0;
1613 if (! is_java_array
)
1615 string_appendn (tname
, *mangled
, r
);
1618 string_appendn (trawname
, *mangled
, r
);
1623 string_append (tname
, "<");
1624 /* get size of template parameter list */
1625 if (!get_count (mangled
, &r
))
1631 /* Create an array for saving the template argument values. */
1632 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
1633 work
->ntmpl_args
= r
;
1634 for (i
= 0; i
< r
; i
++)
1635 work
->tmpl_argvec
[i
] = 0;
1637 for (i
= 0; i
< r
; i
++)
1641 string_append (tname
, ", ");
1643 /* Z for type parameters */
1644 if (**mangled
== 'Z')
1647 /* temp is initialized in do_type */
1648 success
= do_type (work
, mangled
, &temp
);
1651 string_appends (tname
, &temp
);
1655 /* Save the template argument. */
1656 int len
= temp
.p
- temp
.b
;
1657 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1658 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
1659 work
->tmpl_argvec
[i
][len
] = '\0';
1662 string_delete(&temp
);
1668 /* z for template parameters */
1669 else if (**mangled
== 'z')
1673 success
= demangle_template_template_parm (work
, mangled
, tname
);
1676 && (r2
= consume_count (mangled
)) > 0
1677 && (int) strlen (*mangled
) >= r2
)
1679 string_append (tname
, " ");
1680 string_appendn (tname
, *mangled
, r2
);
1683 /* Save the template argument. */
1685 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1686 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
1687 work
->tmpl_argvec
[i
][len
] = '\0';
1701 /* otherwise, value parameter */
1703 /* temp is initialized in do_type */
1704 success
= do_type (work
, mangled
, &temp
);
1705 string_delete(&temp
);
1717 success
= demangle_template_value_parm (work
, mangled
, s
,
1718 (type_kind_t
) success
);
1730 int len
= s
->p
- s
->b
;
1731 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1732 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
1733 work
->tmpl_argvec
[i
][len
] = '\0';
1735 string_appends (tname
, s
);
1743 string_append (tname
, "[]");
1747 if (tname
->p
[-1] == '>')
1748 string_append (tname
, " ");
1749 string_append (tname
, ">");
1752 if (is_type
&& remember
)
1753 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
1756 if (work -> static_type)
1758 string_append (declp, *mangled + 1);
1759 *mangled += strlen (*mangled);
1764 success = demangle_args (work, mangled, declp);
1772 arm_pt (work
, mangled
, n
, anchor
, args
)
1773 struct work_stuff
*work
;
1774 const char *mangled
;
1776 const char **anchor
, **args
;
1778 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1779 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1780 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= mystrstr (mangled
, "__pt__")))
1783 *args
= *anchor
+ 6;
1784 len
= consume_count (args
);
1787 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1793 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
1795 if ((*anchor
= mystrstr (mangled
, "__tm__"))
1796 || (*anchor
= mystrstr (mangled
, "__ps__"))
1797 || (*anchor
= mystrstr (mangled
, "__pt__")))
1800 *args
= *anchor
+ 6;
1801 len
= consume_count (args
);
1804 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1810 else if ((*anchor
= mystrstr (mangled
, "__S")))
1813 *args
= *anchor
+ 3;
1814 len
= consume_count (args
);
1817 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1829 demangle_arm_hp_template (work
, mangled
, n
, declp
)
1830 struct work_stuff
*work
;
1831 const char **mangled
;
1837 const char *e
= *mangled
+ n
;
1840 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1842 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
1844 char *start_spec_args
= NULL
;
1846 /* First check for and omit template specialization pseudo-arguments,
1847 such as in "Spec<#1,#1.*>" */
1848 start_spec_args
= strchr (*mangled
, '<');
1849 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
1850 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
1852 string_appendn (declp
, *mangled
, n
);
1853 (*mangled
) += n
+ 1;
1855 if (work
->temp_start
== -1) /* non-recursive call */
1856 work
->temp_start
= declp
->p
- declp
->b
;
1857 string_append (declp
, "<");
1860 string_clear (&arg
);
1864 /* 'T' signals a type parameter */
1866 if (!do_type (work
, mangled
, &arg
))
1867 goto hpacc_template_args_done
;
1872 /* 'U' or 'S' signals an integral value */
1873 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
1874 goto hpacc_template_args_done
;
1878 /* 'A' signals a named constant expression (literal) */
1879 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
1880 goto hpacc_template_args_done
;
1884 /* Today, 1997-09-03, we have only the above types
1885 of template parameters */
1886 /* FIXME: maybe this should fail and return null */
1887 goto hpacc_template_args_done
;
1889 string_appends (declp
, &arg
);
1890 /* Check if we're at the end of template args.
1891 0 if at end of static member of template class,
1892 _ if done with template args for a function */
1893 if ((**mangled
== '\000') || (**mangled
== '_'))
1896 string_append (declp
, ",");
1898 hpacc_template_args_done
:
1899 string_append (declp
, ">");
1900 string_delete (&arg
);
1901 if (**mangled
== '_')
1905 /* ARM template? (Also handles HP cfront extensions) */
1906 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
1911 string_appendn (declp
, *mangled
, p
- *mangled
);
1912 if (work
->temp_start
== -1) /* non-recursive call */
1913 work
->temp_start
= declp
->p
- declp
->b
;
1914 string_append (declp
, "<");
1915 /* should do error checking here */
1917 string_clear (&arg
);
1919 /* Check for type or literal here */
1922 /* HP cfront extensions to ARM for template args */
1923 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1924 /* FIXME: We handle only numeric literals for HP cfront */
1926 /* A typed constant value follows */
1928 if (!do_type (work
, &args
, &type_str
))
1929 goto cfront_template_args_done
;
1930 string_append (&arg
, "(");
1931 string_appends (&arg
, &type_str
);
1932 string_append (&arg
, ")");
1934 goto cfront_template_args_done
;
1936 /* Now snarf a literal value following 'L' */
1937 if (!snarf_numeric_literal (&args
, &arg
))
1938 goto cfront_template_args_done
;
1942 /* Snarf a literal following 'L' */
1944 if (!snarf_numeric_literal (&args
, &arg
))
1945 goto cfront_template_args_done
;
1948 /* Not handling other HP cfront stuff */
1949 if (!do_type (work
, &args
, &arg
))
1950 goto cfront_template_args_done
;
1952 string_appends (declp
, &arg
);
1953 string_append (declp
, ",");
1955 cfront_template_args_done
:
1956 string_delete (&arg
);
1958 --declp
->p
; /* remove extra comma */
1959 string_append (declp
, ">");
1961 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
1962 && (*mangled
)[9] == 'N'
1963 && (*mangled
)[8] == (*mangled
)[10]
1964 && strchr (cplus_markers
, (*mangled
)[8]))
1966 /* A member of the anonymous namespace. */
1967 string_append (declp
, "{anonymous}");
1971 if (work
->temp_start
== -1) /* non-recursive call only */
1972 work
->temp_start
= 0; /* disable in recursive calls */
1973 string_appendn (declp
, *mangled
, n
);
1978 /* Extract a class name, possibly a template with arguments, from the
1979 mangled string; qualifiers, local class indicators, etc. have
1980 already been dealt with */
1983 demangle_class_name (work
, mangled
, declp
)
1984 struct work_stuff
*work
;
1985 const char **mangled
;
1991 n
= consume_count (mangled
);
1994 if ((int) strlen (*mangled
) >= n
)
1996 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2007 demangle_class -- demangle a mangled class sequence
2012 demangle_class (struct work_stuff *work, const char **mangled,
2017 DECLP points to the buffer into which demangling is being done.
2019 *MANGLED points to the current token to be demangled. On input,
2020 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2021 On exit, it points to the next token after the mangled class on
2022 success, or the first unconsumed token on failure.
2024 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2025 we are demangling a constructor or destructor. In this case
2026 we prepend "class::class" or "class::~class" to DECLP.
2028 Otherwise, we prepend "class::" to the current DECLP.
2030 Reset the constructor/destructor flags once they have been
2031 "consumed". This allows demangle_class to be called later during
2032 the same demangling, to do normal class demangling.
2034 Returns 1 if demangling is successful, 0 otherwise.
2039 demangle_class (work
, mangled
, declp
)
2040 struct work_stuff
*work
;
2041 const char **mangled
;
2047 char *save_class_name_end
= 0;
2049 string_init (&class_name
);
2050 btype
= register_Btype (work
);
2051 if (demangle_class_name (work
, mangled
, &class_name
))
2053 save_class_name_end
= class_name
.p
;
2054 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2056 /* adjust so we don't include template args */
2057 if (work
->temp_start
&& (work
->temp_start
!= -1))
2059 class_name
.p
= class_name
.b
+ work
->temp_start
;
2061 string_prepends (declp
, &class_name
);
2062 if (work
-> destructor
& 1)
2064 string_prepend (declp
, "~");
2065 work
-> destructor
-= 1;
2069 work
-> constructor
-= 1;
2072 class_name
.p
= save_class_name_end
;
2073 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2074 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2075 string_prepend (declp
, SCOPE_STRING (work
));
2076 string_prepends (declp
, &class_name
);
2079 string_delete (&class_name
);
2087 demangle_prefix -- consume the mangled name prefix and find signature
2092 demangle_prefix (struct work_stuff *work, const char **mangled,
2097 Consume and demangle the prefix of the mangled name.
2099 DECLP points to the string buffer into which demangled output is
2100 placed. On entry, the buffer is empty. On exit it contains
2101 the root function name, the demangled operator name, or in some
2102 special cases either nothing or the completely demangled result.
2104 MANGLED points to the current pointer into the mangled name. As each
2105 token of the mangled name is consumed, it is updated. Upon entry
2106 the current mangled name pointer points to the first character of
2107 the mangled name. Upon exit, it should point to the first character
2108 of the signature if demangling was successful, or to the first
2109 unconsumed character if demangling of the prefix was unsuccessful.
2111 Returns 1 on success, 0 otherwise.
2115 demangle_prefix (work
, mangled
, declp
)
2116 struct work_stuff
*work
;
2117 const char **mangled
;
2124 if (strlen(*mangled
) > 6
2125 && (strncmp(*mangled
, "_imp__", 6) == 0
2126 || strncmp(*mangled
, "__imp_", 6) == 0))
2128 /* it's a symbol imported from a PE dynamic library. Check for both
2129 new style prefix _imp__ and legacy __imp_ used by older versions
2132 work
->dllimported
= 1;
2134 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2136 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2137 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2139 if ((*mangled
)[9] == 'D')
2141 /* it's a GNU global destructor to be executed at program exit */
2143 work
->destructor
= 2;
2144 if (gnu_special (work
, mangled
, declp
))
2147 else if ((*mangled
)[9] == 'I')
2149 /* it's a GNU global constructor to be executed at program init */
2151 work
->constructor
= 2;
2152 if (gnu_special (work
, mangled
, declp
))
2157 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2159 /* it's a ARM global destructor to be executed at program exit */
2161 work
->destructor
= 2;
2163 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2165 /* it's a ARM global constructor to be executed at program initial */
2167 work
->constructor
= 2;
2170 /* This block of code is a reduction in strength time optimization
2172 scan = mystrstr (*mangled, "__"); */
2178 scan
= strchr (scan
, '_');
2179 } while (scan
!= NULL
&& *++scan
!= '_');
2181 if (scan
!= NULL
) --scan
;
2186 /* We found a sequence of two or more '_', ensure that we start at
2187 the last pair in the sequence. */
2188 i
= strspn (scan
, "_");
2199 else if (work
-> static_type
)
2201 if (!isdigit ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2206 else if ((scan
== *mangled
)
2207 && (isdigit ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2208 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2210 /* The ARM says nothing about the mangling of local variables.
2211 But cfront mangles local variables by prepending __<nesting_level>
2212 to them. As an extension to ARM demangling we handle this case. */
2213 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2214 && isdigit ((unsigned char)scan
[2]))
2216 *mangled
= scan
+ 2;
2217 consume_count (mangled
);
2218 string_append (declp
, *mangled
);
2219 *mangled
+= strlen (*mangled
);
2224 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2225 names like __Q2_3foo3bar for nested type names. So don't accept
2226 this style of constructor for cfront demangling. A GNU
2227 style member-template constructor starts with 'H'. */
2228 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2229 work
-> constructor
+= 1;
2230 *mangled
= scan
+ 2;
2233 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2235 /* Cfront-style parameterized type. Handled later as a signature. */
2239 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2241 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2242 || (scan
[2] == 'p' && scan
[3] == 's')
2243 || (scan
[2] == 'p' && scan
[3] == 't')))
2245 /* EDG-style parameterized type. Handled later as a signature. */
2249 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2251 else if ((scan
== *mangled
) && !isdigit ((unsigned char)scan
[2])
2252 && (scan
[2] != 't'))
2254 /* Mangled name starts with "__". Skip over any leading '_' characters,
2255 then find the next "__" that separates the prefix from the signature.
2257 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2258 || (arm_special (mangled
, declp
) == 0))
2260 while (*scan
== '_')
2264 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2266 /* No separator (I.E. "__not_mangled"), or empty signature
2267 (I.E. "__not_mangled_either__") */
2274 /* Look for the LAST occurrence of __, allowing names to
2275 have the '__' sequence embedded in them. */
2276 if (!(ARM_DEMANGLING
|| HP_DEMANGLING
))
2278 while ((tmp
= mystrstr (scan
+ 2, "__")) != NULL
)
2281 if (*(scan
+ 2) == '\0')
2284 demangle_function_name (work
, mangled
, declp
, scan
);
2288 else if (*(scan
+ 2) != '\0')
2290 /* Mangled name does not start with "__" but does have one somewhere
2291 in there with non empty stuff after it. Looks like a global
2293 demangle_function_name (work
, mangled
, declp
, scan
);
2297 /* Doesn't look like a mangled name */
2301 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2303 string_append (declp
, *mangled
);
2304 *mangled
+= strlen (*mangled
);
2314 gnu_special -- special handling of gnu mangled strings
2319 gnu_special (struct work_stuff *work, const char **mangled,
2325 Process some special GNU style mangling forms that don't fit
2326 the normal pattern. For example:
2328 _$_3foo (destructor for class foo)
2329 _vt$foo (foo virtual table)
2330 _vt$foo$bar (foo::bar virtual table)
2331 __vt_foo (foo virtual table, new style with thunks)
2332 _3foo$varname (static data member)
2333 _Q22rs2tu$vw (static data member)
2334 __t6vector1Zii (constructor with template)
2335 __thunk_4__$_7ostream (virtual function thunk)
2339 gnu_special (work
, mangled
, declp
)
2340 struct work_stuff
*work
;
2341 const char **mangled
;
2348 if ((*mangled
)[0] == '_'
2349 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2350 && (*mangled
)[2] == '_')
2352 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2354 work
-> destructor
+= 1;
2356 else if ((*mangled
)[0] == '_'
2357 && (((*mangled
)[1] == '_'
2358 && (*mangled
)[2] == 'v'
2359 && (*mangled
)[3] == 't'
2360 && (*mangled
)[4] == '_')
2361 || ((*mangled
)[1] == 'v'
2362 && (*mangled
)[2] == 't'
2363 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2365 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2366 and create the decl. Note that we consume the entire mangled
2367 input string, which means that demangle_signature has no work
2369 if ((*mangled
)[2] == 'v')
2370 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2372 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2373 while (**mangled
!= '\0')
2379 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2382 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2386 if (isdigit((unsigned char)*mangled
[0]))
2388 n
= consume_count(mangled
);
2389 /* We may be seeing a too-large size, or else a
2390 ".<digits>" indicating a static local symbol. In
2391 any case, declare victory and move on; *don't* try
2392 to use n to allocate. */
2393 if (n
> (int) strlen (*mangled
))
2401 n
= strcspn (*mangled
, cplus_markers
);
2403 string_appendn (declp
, *mangled
, n
);
2407 p
= strpbrk (*mangled
, cplus_markers
);
2408 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2412 string_append (declp
, SCOPE_STRING (work
));
2423 string_append (declp
, " virtual table");
2425 else if ((*mangled
)[0] == '_'
2426 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2427 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2429 /* static data member, "_3foo$varname" for example */
2435 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2438 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2441 n
= consume_count (mangled
);
2442 if (n
< 0 || n
> strlen (*mangled
))
2447 string_appendn (declp
, *mangled
, n
);
2450 if (success
&& (p
== *mangled
))
2452 /* Consumed everything up to the cplus_marker, append the
2455 string_append (declp
, SCOPE_STRING (work
));
2456 n
= strlen (*mangled
);
2457 string_appendn (declp
, *mangled
, n
);
2465 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2470 delta
= consume_count (mangled
);
2475 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2480 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2481 string_append (declp
, buf
);
2482 string_append (declp
, method
);
2484 n
= strlen (*mangled
);
2493 else if (strncmp (*mangled
, "__t", 3) == 0
2494 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2496 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2502 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2505 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2508 success
= demangle_fund_type (work
, mangled
, declp
);
2511 if (success
&& **mangled
!= '\0')
2514 string_append (declp
, p
);
2524 recursively_demangle(work
, mangled
, result
, namelength
)
2525 struct work_stuff
*work
;
2526 const char **mangled
;
2530 char * recurse
= (char *)NULL
;
2531 char * recurse_dem
= (char *)NULL
;
2533 recurse
= (char *) xmalloc (namelength
+ 1);
2534 memcpy (recurse
, *mangled
, namelength
);
2535 recurse
[namelength
] = '\000';
2537 recurse_dem
= cplus_demangle (recurse
, work
->options
);
2541 string_append (result
, recurse_dem
);
2546 string_appendn (result
, *mangled
, namelength
);
2549 *mangled
+= namelength
;
2556 arm_special -- special handling of ARM/lucid mangled strings
2561 arm_special (const char **mangled,
2567 Process some special ARM style mangling forms that don't fit
2568 the normal pattern. For example:
2570 __vtbl__3foo (foo virtual table)
2571 __vtbl__3foo__3bar (bar::foo virtual table)
2576 arm_special (mangled
, declp
)
2577 const char **mangled
;
2584 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
2586 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2587 and create the decl. Note that we consume the entire mangled
2588 input string, which means that demangle_signature has no work
2590 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
2591 while (*scan
!= '\0') /* first check it can be demangled */
2593 n
= consume_count (&scan
);
2596 return (0); /* no good */
2599 if (scan
[0] == '_' && scan
[1] == '_')
2604 (*mangled
) += ARM_VTABLE_STRLEN
;
2605 while (**mangled
!= '\0')
2607 n
= consume_count (mangled
);
2609 || n
> strlen (*mangled
))
2611 string_prependn (declp
, *mangled
, n
);
2613 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
2615 string_prepend (declp
, "::");
2619 string_append (declp
, " virtual table");
2632 demangle_qualified -- demangle 'Q' qualified name strings
2637 demangle_qualified (struct work_stuff *, const char *mangled,
2638 string *result, int isfuncname, int append);
2642 Demangle a qualified name, such as "Q25Outer5Inner" which is
2643 the mangled form of "Outer::Inner". The demangled output is
2644 prepended or appended to the result string according to the
2645 state of the append flag.
2647 If isfuncname is nonzero, then the qualified name we are building
2648 is going to be used as a member function name, so if it is a
2649 constructor or destructor function, append an appropriate
2650 constructor or destructor name. I.E. for the above example,
2651 the result for use as a constructor is "Outer::Inner::Inner"
2652 and the result for use as a destructor is "Outer::Inner::~Inner".
2656 Numeric conversion is ASCII dependent (FIXME).
2661 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
2662 struct work_stuff
*work
;
2663 const char **mangled
;
2674 int bindex
= register_Btype (work
);
2676 /* We only make use of ISFUNCNAME if the entity is a constructor or
2678 isfuncname
= (isfuncname
2679 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
2681 string_init (&temp
);
2682 string_init (&last_name
);
2684 if ((*mangled
)[0] == 'K')
2686 /* Squangling qualified name reuse */
2689 idx
= consume_count_with_underscores (mangled
);
2690 if (idx
== -1 || idx
>= work
-> numk
)
2693 string_append (&temp
, work
-> ktypevec
[idx
]);
2696 switch ((*mangled
)[1])
2699 /* GNU mangled name with more than 9 classes. The count is preceded
2700 by an underscore (to distinguish it from the <= 9 case) and followed
2701 by an underscore. */
2703 qualifiers
= atoi (p
);
2704 if (!isdigit ((unsigned char)*p
) || *p
== '0')
2707 /* Skip the digits. */
2708 while (isdigit ((unsigned char)*p
))
2726 /* The count is in a single digit. */
2727 num
[0] = (*mangled
)[1];
2729 qualifiers
= atoi (num
);
2731 /* If there is an underscore after the digit, skip it. This is
2732 said to be for ARM-qualified names, but the ARM makes no
2733 mention of such an underscore. Perhaps cfront uses one. */
2734 if ((*mangled
)[2] == '_')
2749 /* Pick off the names and collect them in the temp buffer in the order
2750 in which they are found, separated by '::'. */
2752 while (qualifiers
-- > 0)
2755 string_clear (&last_name
);
2757 if (*mangled
[0] == '_')
2760 if (*mangled
[0] == 't')
2762 /* Here we always append to TEMP since we will want to use
2763 the template name without the template parameters as a
2764 constructor or destructor name. The appropriate
2765 (parameter-less) value is returned by demangle_template
2766 in LAST_NAME. We do not remember the template type here,
2767 in order to match the G++ mangling algorithm. */
2768 success
= demangle_template(work
, mangled
, &temp
,
2773 else if (*mangled
[0] == 'K')
2777 idx
= consume_count_with_underscores (mangled
);
2778 if (idx
== -1 || idx
>= work
->numk
)
2781 string_append (&temp
, work
->ktypevec
[idx
]);
2784 if (!success
) break;
2791 /* Now recursively demangle the qualifier
2792 * This is necessary to deal with templates in
2793 * mangling styles like EDG */
2794 namelength
= consume_count (mangled
);
2795 if (namelength
== -1)
2800 recursively_demangle(work
, mangled
, &temp
, namelength
);
2804 success
= do_type (work
, mangled
, &last_name
);
2807 string_appends (&temp
, &last_name
);
2812 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
2815 string_append (&temp
, SCOPE_STRING (work
));
2818 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
2820 /* If we are using the result as a function name, we need to append
2821 the appropriate '::' separated constructor or destructor name.
2822 We do this here because this is the most convenient place, where
2823 we already have a pointer to the name and the length of the name. */
2827 string_append (&temp
, SCOPE_STRING (work
));
2828 if (work
-> destructor
& 1)
2829 string_append (&temp
, "~");
2830 string_appends (&temp
, &last_name
);
2833 /* Now either prepend the temp buffer to the result, or append it,
2834 depending upon the state of the append flag. */
2837 string_appends (result
, &temp
);
2840 if (!STRING_EMPTY (result
))
2841 string_append (&temp
, SCOPE_STRING (work
));
2842 string_prepends (result
, &temp
);
2845 string_delete (&last_name
);
2846 string_delete (&temp
);
2854 get_count -- convert an ascii count to integer, consuming tokens
2859 get_count (const char **type, int *count)
2863 Assume that *type points at a count in a mangled name; set
2864 *count to its value, and set *type to the next character after
2865 the count. There are some weird rules in effect here.
2867 If *type does not point at a string of digits, return zero.
2869 If *type points at a string of digits followed by an
2870 underscore, set *count to their value as an integer, advance
2871 *type to point *after the underscore, and return 1.
2873 If *type points at a string of digits not followed by an
2874 underscore, consume only the first digit. Set *count to its
2875 value as an integer, leave *type pointing after that digit,
2878 The excuse for this odd behavior: in the ARM and HP demangling
2879 styles, a type can be followed by a repeat count of the form
2882 `x' is a single digit specifying how many additional copies
2883 of the type to append to the argument list, and
2885 `y' is one or more digits, specifying the zero-based index of
2886 the first repeated argument in the list. Yes, as you're
2887 unmangling the name you can figure this out yourself, but
2890 So, for example, in `bar__3fooFPiN51', the first argument is a
2891 pointer to an integer (`Pi'), and then the next five arguments
2892 are the same (`N5'), and the first repeat is the function's
2893 second argument (`1').
2897 get_count (type
, count
)
2904 if (!isdigit ((unsigned char)**type
))
2910 *count
= **type
- '0';
2912 if (isdigit ((unsigned char)**type
))
2922 while (isdigit ((unsigned char)*p
));
2933 /* RESULT will be initialised here; it will be freed on failure. The
2934 value returned is really a type_kind_t. */
2937 do_type (work
, mangled
, result
)
2938 struct work_stuff
*work
;
2939 const char **mangled
;
2946 const char *remembered_type
;
2949 type_kind_t tk
= tk_none
;
2951 string_init (&btype
);
2952 string_init (&decl
);
2953 string_init (result
);
2957 while (success
&& !done
)
2963 /* A pointer type */
2967 if (! (work
-> options
& DMGL_JAVA
))
2968 string_prepend (&decl
, "*");
2973 /* A reference type */
2976 string_prepend (&decl
, "&");
2985 if (!STRING_EMPTY (&decl
)
2986 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
2988 string_prepend (&decl
, "(");
2989 string_append (&decl
, ")");
2991 string_append (&decl
, "[");
2992 if (**mangled
!= '_')
2993 success
= demangle_template_value_parm (work
, mangled
, &decl
,
2995 if (**mangled
== '_')
2997 string_append (&decl
, "]");
3001 /* A back reference to a previously seen type */
3004 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3010 remembered_type
= work
-> typevec
[n
];
3011 mangled
= &remembered_type
;
3018 if (!STRING_EMPTY (&decl
)
3019 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3021 string_prepend (&decl
, "(");
3022 string_append (&decl
, ")");
3024 /* After picking off the function args, we expect to either find the
3025 function return type (preceded by an '_') or the end of the
3027 if (!demangle_nested_args (work
, mangled
, &decl
)
3028 || (**mangled
!= '_' && **mangled
!= '\0'))
3033 if (success
&& (**mangled
== '_'))
3040 type_quals
= TYPE_UNQUALIFIED
;
3042 member
= **mangled
== 'M';
3044 if (!isdigit ((unsigned char)**mangled
) && **mangled
!= 't')
3050 string_append (&decl
, ")");
3051 string_prepend (&decl
, SCOPE_STRING (work
));
3052 if (isdigit ((unsigned char)**mangled
))
3054 n
= consume_count (mangled
);
3056 || (int) strlen (*mangled
) < n
)
3061 string_prependn (&decl
, *mangled
, n
);
3067 string_init (&temp
);
3068 success
= demangle_template (work
, mangled
, &temp
,
3072 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3073 string_clear (&temp
);
3078 string_prepend (&decl
, "(");
3086 type_quals
|= code_for_qualifier (**mangled
);
3094 if (*(*mangled
)++ != 'F')
3100 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3101 || **mangled
!= '_')
3107 if (! PRINT_ANSI_QUALIFIERS
)
3111 if (type_quals
!= TYPE_UNQUALIFIED
)
3113 APPEND_BLANK (&decl
);
3114 string_append (&decl
, qualifier_string (type_quals
));
3125 if (PRINT_ANSI_QUALIFIERS
)
3127 if (!STRING_EMPTY (&decl
))
3128 string_prepend (&decl
, " ");
3130 string_prepend (&decl
, demangle_qualifier (**mangled
));
3145 if (success
) switch (**mangled
)
3147 /* A qualified name, such as "Outer::Inner". */
3151 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3155 /* A back reference to a previously seen squangled type */
3158 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3161 string_append (result
, work
->btypevec
[n
]);
3166 /* A template parm. We substitute the corresponding argument. */
3171 idx
= consume_count_with_underscores (mangled
);
3174 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3175 || consume_count_with_underscores (mangled
) == -1)
3181 if (work
->tmpl_argvec
)
3182 string_append (result
, work
->tmpl_argvec
[idx
]);
3186 sprintf(buf
, "T%d", idx
);
3187 string_append (result
, buf
);
3195 success
= demangle_fund_type (work
, mangled
, result
);
3197 tk
= (type_kind_t
) success
;
3203 if (!STRING_EMPTY (&decl
))
3205 string_append (result
, " ");
3206 string_appends (result
, &decl
);
3210 string_delete (result
);
3211 string_delete (&decl
);
3214 /* Assume an integral type, if we're not sure. */
3215 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3220 /* Given a pointer to a type string that represents a fundamental type
3221 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3222 string in which the demangled output is being built in RESULT, and
3223 the WORK structure, decode the types and add them to the result.
3228 "Sl" => "signed long"
3229 "CUs" => "const unsigned short"
3231 The value returned is really a type_kind_t. */
3234 demangle_fund_type (work
, mangled
, result
)
3235 struct work_stuff
*work
;
3236 const char **mangled
;
3244 type_kind_t tk
= tk_integral
;
3246 string_init (&btype
);
3248 /* First pick off any type qualifiers. There can be more than one. */
3257 if (PRINT_ANSI_QUALIFIERS
)
3259 if (!STRING_EMPTY (result
))
3260 string_prepend (result
, " ");
3261 string_prepend (result
, demangle_qualifier (**mangled
));
3267 APPEND_BLANK (result
);
3268 string_append (result
, "unsigned");
3270 case 'S': /* signed char only */
3272 APPEND_BLANK (result
);
3273 string_append (result
, "signed");
3277 APPEND_BLANK (result
);
3278 string_append (result
, "__complex");
3286 /* Now pick off the fundamental type. There can be only one. */
3295 APPEND_BLANK (result
);
3296 string_append (result
, "void");
3300 APPEND_BLANK (result
);
3301 string_append (result
, "long long");
3305 APPEND_BLANK (result
);
3306 string_append (result
, "long");
3310 APPEND_BLANK (result
);
3311 string_append (result
, "int");
3315 APPEND_BLANK (result
);
3316 string_append (result
, "short");
3320 APPEND_BLANK (result
);
3321 string_append (result
, "bool");
3326 APPEND_BLANK (result
);
3327 string_append (result
, "char");
3332 APPEND_BLANK (result
);
3333 string_append (result
, "wchar_t");
3338 APPEND_BLANK (result
);
3339 string_append (result
, "long double");
3344 APPEND_BLANK (result
);
3345 string_append (result
, "double");
3350 APPEND_BLANK (result
);
3351 string_append (result
, "float");
3356 if (!isdigit ((unsigned char)**mangled
))
3363 if (**mangled
== '_')
3368 (i
< sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_');
3371 if (**mangled
!= '_')
3381 strncpy (buf
, *mangled
, 2);
3385 sscanf (buf
, "%x", &dec
);
3386 sprintf (buf
, "int%i_t", dec
);
3387 APPEND_BLANK (result
);
3388 string_append (result
, buf
);
3392 /* An explicit type, such as "6mytype" or "7integer" */
3404 int bindex
= register_Btype (work
);
3406 string_init (&btype
);
3407 if (demangle_class_name (work
, mangled
, &btype
)) {
3408 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3409 APPEND_BLANK (result
);
3410 string_appends (result
, &btype
);
3414 string_delete (&btype
);
3419 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3420 string_appends (result
, &btype
);
3428 return success
? ((int) tk
) : 0;
3432 /* Handle a template's value parameter for HP aCC (extension from ARM)
3433 **mangled points to 'S' or 'U' */
3436 do_hpacc_template_const_value (work
, mangled
, result
)
3437 struct work_stuff
*work
;
3438 const char **mangled
;
3443 if (**mangled
!= 'U' && **mangled
!= 'S')
3446 unsigned_const
= (**mangled
== 'U');
3453 string_append (result
, "-");
3459 /* special case for -2^31 */
3460 string_append (result
, "-2147483648");
3467 /* We have to be looking at an integer now */
3468 if (!(isdigit ((unsigned char)**mangled
)))
3471 /* We only deal with integral values for template
3472 parameters -- so it's OK to look only for digits */
3473 while (isdigit ((unsigned char)**mangled
))
3475 char_str
[0] = **mangled
;
3476 string_append (result
, char_str
);
3481 string_append (result
, "U");
3483 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3484 with L or LL suffixes. pai/1997-09-03 */
3486 return 1; /* success */
3489 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3490 **mangled is pointing to the 'A' */
3493 do_hpacc_template_literal (work
, mangled
, result
)
3494 struct work_stuff
*work
;
3495 const char **mangled
;
3498 int literal_len
= 0;
3502 if (**mangled
!= 'A')
3507 literal_len
= consume_count (mangled
);
3509 if (literal_len
<= 0)
3512 /* Literal parameters are names of arrays, functions, etc. and the
3513 canonical representation uses the address operator */
3514 string_append (result
, "&");
3516 /* Now recursively demangle the literal name */
3517 recurse
= (char *) xmalloc (literal_len
+ 1);
3518 memcpy (recurse
, *mangled
, literal_len
);
3519 recurse
[literal_len
] = '\000';
3521 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3525 string_append (result
, recurse_dem
);
3530 string_appendn (result
, *mangled
, literal_len
);
3532 (*mangled
) += literal_len
;
3539 snarf_numeric_literal (args
, arg
)
3546 string_append (arg
, char_str
);
3549 else if (**args
== '+')
3552 if (!isdigit ((unsigned char)**args
))
3555 while (isdigit ((unsigned char)**args
))
3557 char_str
[0] = **args
;
3558 string_append (arg
, char_str
);
3565 /* Demangle the next argument, given by MANGLED into RESULT, which
3566 *should be an uninitialized* string. It will be initialized here,
3567 and free'd should anything go wrong. */
3570 do_arg (work
, mangled
, result
)
3571 struct work_stuff
*work
;
3572 const char **mangled
;
3575 /* Remember where we started so that we can record the type, for
3576 non-squangling type remembering. */
3577 const char *start
= *mangled
;
3579 string_init (result
);
3581 if (work
->nrepeats
> 0)
3585 if (work
->previous_argument
== 0)
3588 /* We want to reissue the previous type in this argument list. */
3589 string_appends (result
, work
->previous_argument
);
3593 if (**mangled
== 'n')
3595 /* A squangling-style repeat. */
3597 work
->nrepeats
= consume_count(mangled
);
3599 if (work
->nrepeats
<= 0)
3600 /* This was not a repeat count after all. */
3603 if (work
->nrepeats
> 9)
3605 if (**mangled
!= '_')
3606 /* The repeat count should be followed by an '_' in this
3613 /* Now, the repeat is all set up. */
3614 return do_arg (work
, mangled
, result
);
3617 /* Save the result in WORK->previous_argument so that we can find it
3618 if it's repeated. Note that saving START is not good enough: we
3619 do not want to add additional types to the back-referenceable
3620 type vector when processing a repeated type. */
3621 if (work
->previous_argument
)
3622 string_clear (work
->previous_argument
);
3625 work
->previous_argument
= (string
*) xmalloc (sizeof (string
));
3626 string_init (work
->previous_argument
);
3629 if (!do_type (work
, mangled
, work
->previous_argument
))
3632 string_appends (result
, work
->previous_argument
);
3634 remember_type (work
, start
, *mangled
- start
);
3639 remember_type (work
, start
, len
)
3640 struct work_stuff
*work
;
3646 if (work
->forgetting_types
)
3649 if (work
-> ntypes
>= work
-> typevec_size
)
3651 if (work
-> typevec_size
== 0)
3653 work
-> typevec_size
= 3;
3655 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
3659 work
-> typevec_size
*= 2;
3661 = (char **) xrealloc ((char *)work
-> typevec
,
3662 sizeof (char *) * work
-> typevec_size
);
3665 tem
= xmalloc (len
+ 1);
3666 memcpy (tem
, start
, len
);
3668 work
-> typevec
[work
-> ntypes
++] = tem
;
3672 /* Remember a K type class qualifier. */
3674 remember_Ktype (work
, start
, len
)
3675 struct work_stuff
*work
;
3681 if (work
-> numk
>= work
-> ksize
)
3683 if (work
-> ksize
== 0)
3687 = (char **) xmalloc (sizeof (char *) * work
-> ksize
);
3693 = (char **) xrealloc ((char *)work
-> ktypevec
,
3694 sizeof (char *) * work
-> ksize
);
3697 tem
= xmalloc (len
+ 1);
3698 memcpy (tem
, start
, len
);
3700 work
-> ktypevec
[work
-> numk
++] = tem
;
3703 /* Register a B code, and get an index for it. B codes are registered
3704 as they are seen, rather than as they are completed, so map<temp<char> >
3705 registers map<temp<char> > as B0, and temp<char> as B1 */
3708 register_Btype (work
)
3709 struct work_stuff
*work
;
3713 if (work
-> numb
>= work
-> bsize
)
3715 if (work
-> bsize
== 0)
3719 = (char **) xmalloc (sizeof (char *) * work
-> bsize
);
3725 = (char **) xrealloc ((char *)work
-> btypevec
,
3726 sizeof (char *) * work
-> bsize
);
3729 ret
= work
-> numb
++;
3730 work
-> btypevec
[ret
] = NULL
;
3734 /* Store a value into a previously registered B code type. */
3737 remember_Btype (work
, start
, len
, index
)
3738 struct work_stuff
*work
;
3744 tem
= xmalloc (len
+ 1);
3745 memcpy (tem
, start
, len
);
3747 work
-> btypevec
[index
] = tem
;
3750 /* Lose all the info related to B and K type codes. */
3752 forget_B_and_K_types (work
)
3753 struct work_stuff
*work
;
3757 while (work
-> numk
> 0)
3759 i
= --(work
-> numk
);
3760 if (work
-> ktypevec
[i
] != NULL
)
3762 free (work
-> ktypevec
[i
]);
3763 work
-> ktypevec
[i
] = NULL
;
3767 while (work
-> numb
> 0)
3769 i
= --(work
-> numb
);
3770 if (work
-> btypevec
[i
] != NULL
)
3772 free (work
-> btypevec
[i
]);
3773 work
-> btypevec
[i
] = NULL
;
3777 /* Forget the remembered types, but not the type vector itself. */
3781 struct work_stuff
*work
;
3785 while (work
-> ntypes
> 0)
3787 i
= --(work
-> ntypes
);
3788 if (work
-> typevec
[i
] != NULL
)
3790 free (work
-> typevec
[i
]);
3791 work
-> typevec
[i
] = NULL
;
3796 /* Process the argument list part of the signature, after any class spec
3797 has been consumed, as well as the first 'F' character (if any). For
3800 "__als__3fooRT0" => process "RT0"
3801 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3803 DECLP must be already initialised, usually non-empty. It won't be freed
3806 Note that g++ differs significantly from ARM and lucid style mangling
3807 with regards to references to previously seen types. For example, given
3808 the source fragment:
3812 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3815 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3816 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3818 g++ produces the names:
3823 while lcc (and presumably other ARM style compilers as well) produces:
3825 foo__FiR3fooT1T2T1T2
3826 __ct__3fooFiR3fooT1T2T1T2
3828 Note that g++ bases its type numbers starting at zero and counts all
3829 previously seen types, while lucid/ARM bases its type numbers starting
3830 at one and only considers types after it has seen the 'F' character
3831 indicating the start of the function args. For lucid/ARM style, we
3832 account for this difference by discarding any previously seen types when
3833 we see the 'F' character, and subtracting one from the type number
3839 demangle_args (work
, mangled
, declp
)
3840 struct work_stuff
*work
;
3841 const char **mangled
;
3851 if (PRINT_ARG_TYPES
)
3853 string_append (declp
, "(");
3854 if (**mangled
== '\0')
3856 string_append (declp
, "void");
3860 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
3861 || work
->nrepeats
> 0)
3863 if ((**mangled
== 'N') || (**mangled
== 'T'))
3865 temptype
= *(*mangled
)++;
3867 if (temptype
== 'N')
3869 if (!get_count (mangled
, &r
))
3878 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
3880 /* If we have 10 or more types we might have more than a 1 digit
3881 index so we'll have to consume the whole count here. This
3882 will lose if the next thing is a type name preceded by a
3883 count but it's impossible to demangle that case properly
3884 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3885 Pc, ...)" or "(..., type12, char *, ...)" */
3886 if ((t
= consume_count(mangled
)) <= 0)
3893 if (!get_count (mangled
, &t
))
3898 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
3902 /* Validate the type index. Protect against illegal indices from
3903 malformed type strings. */
3904 if ((t
< 0) || (t
>= work
-> ntypes
))
3908 while (work
->nrepeats
> 0 || --r
>= 0)
3910 tem
= work
-> typevec
[t
];
3911 if (need_comma
&& PRINT_ARG_TYPES
)
3913 string_append (declp
, ", ");
3915 if (!do_arg (work
, &tem
, &arg
))
3919 if (PRINT_ARG_TYPES
)
3921 string_appends (declp
, &arg
);
3923 string_delete (&arg
);
3929 if (need_comma
&& PRINT_ARG_TYPES
)
3930 string_append (declp
, ", ");
3931 if (!do_arg (work
, mangled
, &arg
))
3933 if (PRINT_ARG_TYPES
)
3934 string_appends (declp
, &arg
);
3935 string_delete (&arg
);
3940 if (**mangled
== 'e')
3943 if (PRINT_ARG_TYPES
)
3947 string_append (declp
, ",");
3949 string_append (declp
, "...");
3953 if (PRINT_ARG_TYPES
)
3955 string_append (declp
, ")");
3960 /* Like demangle_args, but for demangling the argument lists of function
3961 and method pointers or references, not top-level declarations. */
3964 demangle_nested_args (work
, mangled
, declp
)
3965 struct work_stuff
*work
;
3966 const char **mangled
;
3969 string
* saved_previous_argument
;
3973 /* The G++ name-mangling algorithm does not remember types on nested
3974 argument lists, unless -fsquangling is used, and in that case the
3975 type vector updated by remember_type is not used. So, we turn
3976 off remembering of types here. */
3977 ++work
->forgetting_types
;
3979 /* For the repeat codes used with -fsquangling, we must keep track of
3980 the last argument. */
3981 saved_previous_argument
= work
->previous_argument
;
3982 saved_nrepeats
= work
->nrepeats
;
3983 work
->previous_argument
= 0;
3986 /* Actually demangle the arguments. */
3987 result
= demangle_args (work
, mangled
, declp
);
3989 /* Restore the previous_argument field. */
3990 if (work
->previous_argument
)
3991 string_delete (work
->previous_argument
);
3992 work
->previous_argument
= saved_previous_argument
;
3993 --work
->forgetting_types
;
3994 work
->nrepeats
= saved_nrepeats
;
4000 demangle_function_name (work
, mangled
, declp
, scan
)
4001 struct work_stuff
*work
;
4002 const char **mangled
;
4010 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4011 string_need (declp
, 1);
4012 *(declp
-> p
) = '\0';
4014 /* Consume the function name, including the "__" separating the name
4015 from the signature. We are guaranteed that SCAN points to the
4018 (*mangled
) = scan
+ 2;
4019 /* We may be looking at an instantiation of a template function:
4020 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4021 following _F marks the start of the function arguments. Handle
4022 the template arguments first. */
4024 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4026 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4027 /* This leaves MANGLED pointing to the 'F' marking func args */
4030 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4033 /* See if we have an ARM style constructor or destructor operator.
4034 If so, then just record it, clear the decl, and return.
4035 We can't build the actual constructor/destructor decl until later,
4036 when we recover the class name from the signature. */
4038 if (strcmp (declp
-> b
, "__ct") == 0)
4040 work
-> constructor
+= 1;
4041 string_clear (declp
);
4044 else if (strcmp (declp
-> b
, "__dt") == 0)
4046 work
-> destructor
+= 1;
4047 string_clear (declp
);
4052 if (declp
->p
- declp
->b
>= 3
4053 && declp
->b
[0] == 'o'
4054 && declp
->b
[1] == 'p'
4055 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4057 /* see if it's an assignment expression */
4058 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4059 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4061 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4063 int len
= declp
->p
- declp
->b
- 10;
4064 if ((int) strlen (optable
[i
].in
) == len
4065 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4067 string_clear (declp
);
4068 string_append (declp
, "operator");
4069 string_append (declp
, optable
[i
].out
);
4070 string_append (declp
, "=");
4077 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4079 int len
= declp
->p
- declp
->b
- 3;
4080 if ((int) strlen (optable
[i
].in
) == len
4081 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4083 string_clear (declp
);
4084 string_append (declp
, "operator");
4085 string_append (declp
, optable
[i
].out
);
4091 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4092 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4094 /* type conversion operator */
4096 if (do_type (work
, &tem
, &type
))
4098 string_clear (declp
);
4099 string_append (declp
, "operator ");
4100 string_appends (declp
, &type
);
4101 string_delete (&type
);
4104 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4105 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4108 /* type conversion operator. */
4110 if (do_type (work
, &tem
, &type
))
4112 string_clear (declp
);
4113 string_append (declp
, "operator ");
4114 string_appends (declp
, &type
);
4115 string_delete (&type
);
4118 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4119 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
4120 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
4122 if (declp
->b
[4] == '\0')
4125 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4127 if (strlen (optable
[i
].in
) == 2
4128 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4130 string_clear (declp
);
4131 string_append (declp
, "operator");
4132 string_append (declp
, optable
[i
].out
);
4139 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4142 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4144 if (strlen (optable
[i
].in
) == 3
4145 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4147 string_clear (declp
);
4148 string_append (declp
, "operator");
4149 string_append (declp
, optable
[i
].out
);
4158 /* a mini string-handling package */
4173 s
->p
= s
->b
= xmalloc (n
);
4176 else if (s
->e
- s
->p
< n
)
4181 s
->b
= xrealloc (s
->b
, n
);
4194 s
->b
= s
->e
= s
->p
= NULL
;
4202 s
->b
= s
->p
= s
->e
= NULL
;
4218 return (s
->b
== s
->p
);
4224 string_append (p
, s
)
4229 if (s
== NULL
|| *s
== '\0')
4233 memcpy (p
->p
, s
, n
);
4238 string_appends (p
, s
)
4247 memcpy (p
->p
, s
->b
, n
);
4253 string_appendn (p
, s
, n
)
4261 memcpy (p
->p
, s
, n
);
4267 string_prepend (p
, s
)
4271 if (s
!= NULL
&& *s
!= '\0')
4273 string_prependn (p
, s
, strlen (s
));
4278 string_prepends (p
, s
)
4283 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4288 string_prependn (p
, s
, n
)
4298 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4302 memcpy (p
->b
, s
, n
);
4307 /* To generate a standalone demangler program for testing purposes,
4308 just compile and link this file with -DMAIN and libiberty.a. When
4309 run, it demangles each command line arg, or each stdin string, and
4310 prints the result on stdout. */
4316 static char *program_name
;
4317 static char *program_version
= VERSION
;
4318 static int flags
= DMGL_PARAMS
| DMGL_ANSI
;
4320 static void demangle_it
PARAMS ((char *));
4321 static void usage
PARAMS ((FILE *, int));
4322 static void fatal
PARAMS ((char *));
4325 demangle_it (mangled_name
)
4330 result
= cplus_demangle (mangled_name
, flags
);
4333 printf ("%s\n", mangled_name
);
4337 printf ("%s\n", result
);
4343 usage (stream
, status
)
4348 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4349 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4350 [--help] [--version] [arg...]\n",
4355 #define MBUF_SIZE 32767
4356 char mbuffer
[MBUF_SIZE
];
4358 /* Defined in the automatically-generated underscore.c. */
4359 extern int prepends_underscore
;
4361 int strip_underscore
= 0;
4363 static struct option long_options
[] = {
4364 {"strip-underscores", no_argument
, 0, '_'},
4365 {"format", required_argument
, 0, 's'},
4366 {"help", no_argument
, 0, 'h'},
4367 {"java", no_argument
, 0, 'j'},
4368 {"no-strip-underscores", no_argument
, 0, 'n'},
4369 {"version", no_argument
, 0, 'v'},
4370 {0, no_argument
, 0, 0}
4373 /* More 'friendly' abort that prints the line and file.
4374 config.h can #define abort fancy_abort if you like that sort of thing. */
4379 fatal ("Internal gcc abort.");
4383 /* Fill in TABLE so that TABLE[C] is true iff C (as an unsigned char)
4384 is a valid symbol component, in the standard assembler symbol
4387 standard_symbol_alphabet (char *table
)
4391 for (c
= 0; c
< 256; c
++)
4392 table
[c
] = isalnum(c
);
4400 /* Fill in TABLE so that TABLE[C] is true iff C (as an unsigned char)
4401 is a valid symbol name component in an HP object file.
4403 Note that, since HP's compiler generates object code straight from
4404 C++ source, without going through an assembler, its mangled
4405 identifiers can use all sorts of characters that no assembler would
4406 tolerate, so the alphabet this function creates is a little odd.
4407 Here are some sample mangled identifiers offered by HP:
4409 typeid*__XT24AddressIndExpClassMember_
4410 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4411 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4413 This still seems really weird to me, since nowhere else in this
4414 file is there anything to recognize curly brackets, parens, etc.
4415 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4416 this is right, but I still strongly suspect that there's a
4417 misunderstanding here.
4419 If we decide it's better for c++filt to use HP's assembler syntax
4420 to scrape identifiers out of its input, here's the definition of
4421 the symbol name syntax from the HP assembler manual:
4423 Symbols are composed of uppercase and lowercase letters, decimal
4424 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4425 underscore (_). A symbol can begin with a letter, digit underscore or
4426 dollar sign. If a symbol begins with a digit, it must contain a
4427 non-digit character.
4431 hp_symbol_alphabet (char *table
)
4435 standard_symbol_alphabet (table
);
4437 for (c
= "<>#,*&[]:(){}"; *c
; c
++)
4438 table
[(unsigned char) *c
] = 1;
4449 char symbol_alphabet
[256];
4451 program_name
= argv
[0];
4453 strip_underscore
= prepends_underscore
;
4455 while ((c
= getopt_long (argc
, argv
, "_ns:j", long_options
, (int *) 0)) != EOF
)
4465 strip_underscore
= 0;
4468 printf ("GNU %s (C++ demangler), version %s\n", program_name
, program_version
);
4471 strip_underscore
= 1;
4477 if (strcmp (optarg
, "gnu") == 0)
4479 current_demangling_style
= gnu_demangling
;
4481 else if (strcmp (optarg
, "lucid") == 0)
4483 current_demangling_style
= lucid_demangling
;
4485 else if (strcmp (optarg
, "arm") == 0)
4487 current_demangling_style
= arm_demangling
;
4489 else if (strcmp (optarg
, "hp") == 0)
4491 current_demangling_style
= hp_demangling
;
4493 else if (strcmp (optarg
, "edg") == 0)
4495 current_demangling_style
= edg_demangling
;
4499 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
4500 program_name
, optarg
);
4509 for ( ; optind
< argc
; optind
++)
4511 demangle_it (argv
[optind
]);
4516 switch (current_demangling_style
)
4518 case gnu_demangling
:
4519 case lucid_demangling
:
4520 case arm_demangling
:
4521 case edg_demangling
:
4522 standard_symbol_alphabet (symbol_alphabet
);
4525 hp_symbol_alphabet (symbol_alphabet
);
4528 /* Folks should explicitly indicate the appropriate alphabet for
4529 each demangling. Providing a default would allow the
4530 question to go unconsidered. */
4538 /* Try to read a label. */
4539 while (c
!= EOF
&& symbol_alphabet
[c
])
4541 if (i
>= MBUF_SIZE
-1)
4550 if (mbuffer
[0] == '.')
4552 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
4560 result
= cplus_demangle (mbuffer
+ skip_first
, flags
);
4563 if (mbuffer
[0] == '.')
4565 fputs (result
, stdout
);
4569 fputs (mbuffer
, stdout
);
4586 fprintf (stderr
, "%s: %s\n", program_name
, str
);
4594 register PTR value
= (PTR
) malloc (size
);
4596 fatal ("virtual memory exhausted");
4601 xrealloc (ptr
, size
)
4605 register PTR value
= (PTR
) realloc (ptr
, size
);
4607 fatal ("virtual memory exhausted");