1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 Libiberty is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with libiberty; see the file COPYING.LIB. If
20 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
25 This file imports xmalloc and xrealloc, which are like malloc and
26 realloc except that they generate a fatal error if there is no
29 /* This file lives in both GCC and libiberty. When making changes, please
30 try not to break either. */
37 #include <sys/types.h>
49 #undef CURRENT_DEMANGLING_STYLE
50 #define CURRENT_DEMANGLING_STYLE work->options
52 #include "libiberty.h"
54 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
56 /* A value at least one greater than the maximum number of characters
57 that will be output when using the `%d' format with `printf'. */
58 #define INTBUF_SIZE 32
60 extern void fancy_abort
PARAMS ((void)) ATTRIBUTE_NORETURN
;
62 static const char *mystrstr
PARAMS ((const char *, const char *));
68 register const char *p
= s1
;
69 register int len
= strlen (s2
);
71 for (; (p
= strchr (p
, *s2
)) != 0; p
++)
73 if (strncmp (p
, s2
, len
) == 0)
81 /* In order to allow a single demangler executable to demangle strings
82 using various common values of CPLUS_MARKER, as well as any specific
83 one set at compile time, we maintain a string containing all the
84 commonly used ones, and check to see if the marker we are looking for
85 is in that string. CPLUS_MARKER is usually '$' on systems where the
86 assembler can deal with that. Where the assembler can't, it's usually
87 '.' (but on many systems '.' is used for other things). We put the
88 current defined CPLUS_MARKER first (which defaults to '$'), followed
89 by the next most common value, followed by an explicit '$' in case
90 the value of CPLUS_MARKER is not '$'.
92 We could avoid this if we could just get g++ to tell us what the actual
93 cplus marker character is as part of the debug information, perhaps by
94 ensuring that it is the character that terminates the gcc<n>_compiled
95 marker symbol (FIXME). */
97 #if !defined (CPLUS_MARKER)
98 #define CPLUS_MARKER '$'
101 enum demangling_styles current_demangling_style
= gnu_demangling
;
103 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
105 static char char_str
[2] = { '\000', '\000' };
108 set_cplus_marker_for_demangling (ch
)
111 cplus_markers
[0] = ch
;
114 typedef struct string
/* Beware: these aren't required to be */
115 { /* '\0' terminated. */
116 char *b
; /* pointer to start of string */
117 char *p
; /* pointer after last character */
118 char *e
; /* pointer after end of allocated space */
121 /* Stuff that is shared between sub-routines.
122 Using a shared structure allows cplus_demangle to be reentrant. */
138 int static_type
; /* A static member function */
139 int temp_start
; /* index in demangled to start of template args */
140 int type_quals
; /* The type qualifiers. */
141 int dllimported
; /* Symbol imported from a PE DLL */
142 char **tmpl_argvec
; /* Template function arguments. */
143 int ntmpl_args
; /* The number of template function arguments. */
144 int forgetting_types
; /* Nonzero if we are not remembering the types
146 string
* previous_argument
; /* The last function argument demangled. */
147 int nrepeats
; /* The number of times to repeat the previous
151 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
152 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
154 static const struct optable
160 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
161 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
162 {"new", " new", 0}, /* old (1.91, and 1.x) */
163 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
164 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
165 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
166 {"as", "=", DMGL_ANSI
}, /* ansi */
167 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
168 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
169 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
170 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
171 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
172 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
173 {"plus", "+", 0}, /* old */
174 {"pl", "+", DMGL_ANSI
}, /* ansi */
175 {"apl", "+=", DMGL_ANSI
}, /* ansi */
176 {"minus", "-", 0}, /* old */
177 {"mi", "-", DMGL_ANSI
}, /* ansi */
178 {"ami", "-=", DMGL_ANSI
}, /* ansi */
179 {"mult", "*", 0}, /* old */
180 {"ml", "*", DMGL_ANSI
}, /* ansi */
181 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
182 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
183 {"convert", "+", 0}, /* old (unary +) */
184 {"negate", "-", 0}, /* old (unary -) */
185 {"trunc_mod", "%", 0}, /* old */
186 {"md", "%", DMGL_ANSI
}, /* ansi */
187 {"amd", "%=", DMGL_ANSI
}, /* ansi */
188 {"trunc_div", "/", 0}, /* old */
189 {"dv", "/", DMGL_ANSI
}, /* ansi */
190 {"adv", "/=", DMGL_ANSI
}, /* ansi */
191 {"truth_andif", "&&", 0}, /* old */
192 {"aa", "&&", DMGL_ANSI
}, /* ansi */
193 {"truth_orif", "||", 0}, /* old */
194 {"oo", "||", DMGL_ANSI
}, /* ansi */
195 {"truth_not", "!", 0}, /* old */
196 {"nt", "!", DMGL_ANSI
}, /* ansi */
197 {"postincrement","++", 0}, /* old */
198 {"pp", "++", DMGL_ANSI
}, /* ansi */
199 {"postdecrement","--", 0}, /* old */
200 {"mm", "--", DMGL_ANSI
}, /* ansi */
201 {"bit_ior", "|", 0}, /* old */
202 {"or", "|", DMGL_ANSI
}, /* ansi */
203 {"aor", "|=", DMGL_ANSI
}, /* ansi */
204 {"bit_xor", "^", 0}, /* old */
205 {"er", "^", DMGL_ANSI
}, /* ansi */
206 {"aer", "^=", DMGL_ANSI
}, /* ansi */
207 {"bit_and", "&", 0}, /* old */
208 {"ad", "&", DMGL_ANSI
}, /* ansi */
209 {"aad", "&=", DMGL_ANSI
}, /* ansi */
210 {"bit_not", "~", 0}, /* old */
211 {"co", "~", DMGL_ANSI
}, /* ansi */
212 {"call", "()", 0}, /* old */
213 {"cl", "()", DMGL_ANSI
}, /* ansi */
214 {"alshift", "<<", 0}, /* old */
215 {"ls", "<<", DMGL_ANSI
}, /* ansi */
216 {"als", "<<=", DMGL_ANSI
}, /* ansi */
217 {"arshift", ">>", 0}, /* old */
218 {"rs", ">>", DMGL_ANSI
}, /* ansi */
219 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
220 {"component", "->", 0}, /* old */
221 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
222 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
223 {"indirect", "*", 0}, /* old */
224 {"method_call", "->()", 0}, /* old */
225 {"addr", "&", 0}, /* old (unary &) */
226 {"array", "[]", 0}, /* old */
227 {"vc", "[]", DMGL_ANSI
}, /* ansi */
228 {"compound", ", ", 0}, /* old */
229 {"cm", ", ", DMGL_ANSI
}, /* ansi */
230 {"cond", "?:", 0}, /* old */
231 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
232 {"max", ">?", 0}, /* old */
233 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
234 {"min", "<?", 0}, /* old */
235 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
236 {"nop", "", 0}, /* old (for operator=) */
237 {"rm", "->*", DMGL_ANSI
}, /* ansi */
238 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
241 /* These values are used to indicate the various type varieties.
242 They are all non-zero so that they can be used as `success'
244 typedef enum type_kind_t
255 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
256 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
257 string_prepend(str, " ");}
258 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
259 string_append(str, " ");}
260 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
262 /* The scope separator appropriate for the language being demangled. */
264 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
266 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
267 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
269 /* Prototypes for local functions */
272 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
275 squangle_mop_up
PARAMS ((struct work_stuff
*));
279 demangle_method_args
PARAMS ((struct work_stuff
*, const char **, string
*));
283 internal_cplus_demangle
PARAMS ((struct work_stuff
*, const char *));
286 demangle_template_template_parm
PARAMS ((struct work_stuff
*work
,
287 const char **, string
*));
290 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*,
291 string
*, int, int));
294 arm_pt
PARAMS ((struct work_stuff
*, const char *, int, const char **,
298 demangle_class_name
PARAMS ((struct work_stuff
*, const char **, string
*));
301 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
305 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
308 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
311 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
314 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
317 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
320 arm_special
PARAMS ((const char **, string
*));
323 string_need
PARAMS ((string
*, int));
326 string_delete
PARAMS ((string
*));
329 string_init
PARAMS ((string
*));
332 string_clear
PARAMS ((string
*));
336 string_empty
PARAMS ((string
*));
340 string_append
PARAMS ((string
*, const char *));
343 string_appends
PARAMS ((string
*, string
*));
346 string_appendn
PARAMS ((string
*, const char *, int));
349 string_prepend
PARAMS ((string
*, const char *));
352 string_prependn
PARAMS ((string
*, const char *, int));
355 string_append_template_idx
PARAMS ((string
*, int));
358 get_count
PARAMS ((const char **, int *));
361 consume_count
PARAMS ((const char **));
364 consume_count_with_underscores
PARAMS ((const char**));
367 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
370 demangle_nested_args
PARAMS ((struct work_stuff
*, const char**, string
*));
373 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
376 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
379 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
383 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
386 remember_Btype
PARAMS ((struct work_stuff
*, const char *, int, int));
389 register_Btype
PARAMS ((struct work_stuff
*));
392 remember_Ktype
PARAMS ((struct work_stuff
*, const char *, int));
395 forget_types
PARAMS ((struct work_stuff
*));
398 forget_B_and_K_types
PARAMS ((struct work_stuff
*));
401 string_prepends
PARAMS ((string
*, string
*));
404 demangle_template_value_parm
PARAMS ((struct work_stuff
*, const char**,
405 string
*, type_kind_t
));
408 do_hpacc_template_const_value
PARAMS ((struct work_stuff
*, const char **, string
*));
411 do_hpacc_template_literal
PARAMS ((struct work_stuff
*, const char **, string
*));
414 snarf_numeric_literal
PARAMS ((const char **, string
*));
416 /* There is a TYPE_QUAL value for each type qualifier. They can be
417 combined by bitwise-or to form the complete set of qualifiers for a
420 #define TYPE_UNQUALIFIED 0x0
421 #define TYPE_QUAL_CONST 0x1
422 #define TYPE_QUAL_VOLATILE 0x2
423 #define TYPE_QUAL_RESTRICT 0x4
426 code_for_qualifier
PARAMS ((int));
429 qualifier_string
PARAMS ((int));
432 demangle_qualifier
PARAMS ((int));
435 demangle_expression
PARAMS ((struct work_stuff
*, const char **, string
*,
439 demangle_integral_value
PARAMS ((struct work_stuff
*, const char **,
443 demangle_real_value
PARAMS ((struct work_stuff
*, const char **, string
*));
446 demangle_arm_hp_template
PARAMS ((struct work_stuff
*, const char **, int,
450 recursively_demangle
PARAMS ((struct work_stuff
*, const char **, string
*,
454 standard_symbol_characters
PARAMS ((void));
457 hp_symbol_characters
PARAMS ((void));
459 /* Translate count to integer, consuming tokens in the process.
460 Conversion terminates on the first non-digit character.
462 Trying to consume something that isn't a count results in no
463 consumption of input and a return of -1.
465 Overflow consumes the rest of the digits, and returns -1. */
473 if (! isdigit ((unsigned char)**type
))
476 while (isdigit ((unsigned char)**type
))
480 /* Check for overflow.
481 We assume that count is represented using two's-complement;
482 no power of two is divisible by ten, so if an overflow occurs
483 when multiplying by ten, the result will not be a multiple of
485 if ((count
% 10) != 0)
487 while (isdigit ((unsigned char) **type
))
492 count
+= **type
- '0';
500 /* Like consume_count, but for counts that are preceded and followed
501 by '_' if they are greater than 10. Also, -1 is returned for
502 failure, since 0 can be a valid value. */
505 consume_count_with_underscores (mangled
)
506 const char **mangled
;
510 if (**mangled
== '_')
513 if (!isdigit ((unsigned char)**mangled
))
516 idx
= consume_count (mangled
);
517 if (**mangled
!= '_')
518 /* The trailing underscore was missing. */
525 if (**mangled
< '0' || **mangled
> '9')
528 idx
= **mangled
- '0';
535 /* C is the code for a type-qualifier. Return the TYPE_QUAL
536 corresponding to this qualifier. */
539 code_for_qualifier (c
)
545 return TYPE_QUAL_CONST
;
548 return TYPE_QUAL_VOLATILE
;
551 return TYPE_QUAL_RESTRICT
;
557 /* C was an invalid qualifier. */
561 /* Return the string corresponding to the qualifiers given by
565 qualifier_string (type_quals
)
570 case TYPE_UNQUALIFIED
:
573 case TYPE_QUAL_CONST
:
576 case TYPE_QUAL_VOLATILE
:
579 case TYPE_QUAL_RESTRICT
:
582 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
583 return "const volatile";
585 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
586 return "const __restrict";
588 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
589 return "volatile __restrict";
591 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
592 return "const volatile __restrict";
598 /* TYPE_QUALS was an invalid qualifier set. */
602 /* C is the code for a type-qualifier. Return the string
603 corresponding to this qualifier. This function should only be
604 called with a valid qualifier code. */
607 demangle_qualifier (c
)
610 return qualifier_string (code_for_qualifier (c
));
614 cplus_demangle_opname (opname
, result
, options
)
621 struct work_stuff work
[1];
624 len
= strlen(opname
);
627 memset ((char *) work
, 0, sizeof (work
));
628 work
->options
= options
;
630 if (opname
[0] == '_' && opname
[1] == '_'
631 && opname
[2] == 'o' && opname
[3] == 'p')
634 /* type conversion operator. */
636 if (do_type (work
, &tem
, &type
))
638 strcat (result
, "operator ");
639 strncat (result
, type
.b
, type
.p
- type
.b
);
640 string_delete (&type
);
644 else if (opname
[0] == '_' && opname
[1] == '_'
645 && opname
[2] >= 'a' && opname
[2] <= 'z'
646 && opname
[3] >= 'a' && opname
[3] <= 'z')
648 if (opname
[4] == '\0')
652 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
654 if (strlen (optable
[i
].in
) == 2
655 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
657 strcat (result
, "operator");
658 strcat (result
, optable
[i
].out
);
666 if (opname
[2] == 'a' && opname
[5] == '\0')
670 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
672 if (strlen (optable
[i
].in
) == 3
673 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
675 strcat (result
, "operator");
676 strcat (result
, optable
[i
].out
);
687 && strchr (cplus_markers
, opname
[2]) != NULL
)
689 /* see if it's an assignment expression */
690 if (len
>= 10 /* op$assign_ */
691 && memcmp (opname
+ 3, "assign_", 7) == 0)
694 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
697 if ((int) strlen (optable
[i
].in
) == len1
698 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
700 strcat (result
, "operator");
701 strcat (result
, optable
[i
].out
);
702 strcat (result
, "=");
711 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
714 if ((int) strlen (optable
[i
].in
) == len1
715 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
717 strcat (result
, "operator");
718 strcat (result
, optable
[i
].out
);
725 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
726 && strchr (cplus_markers
, opname
[4]) != NULL
)
728 /* type conversion operator */
730 if (do_type (work
, &tem
, &type
))
732 strcat (result
, "operator ");
733 strncat (result
, type
.b
, type
.p
- type
.b
);
734 string_delete (&type
);
738 squangle_mop_up (work
);
742 /* Takes operator name as e.g. "++" and returns mangled
743 operator name (e.g. "postincrement_expr"), or NULL if not found.
745 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
746 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
749 cplus_mangle_opname (opname
, options
)
756 len
= strlen (opname
);
757 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
759 if ((int) strlen (optable
[i
].out
) == len
760 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
761 && memcmp (optable
[i
].out
, opname
, len
) == 0)
762 return optable
[i
].in
;
767 /* char *cplus_demangle (const char *mangled, int options)
769 If MANGLED is a mangled function name produced by GNU C++, then
770 a pointer to a malloced string giving a C++ representation
771 of the name will be returned; otherwise NULL will be returned.
772 It is the caller's responsibility to free the string which
775 The OPTIONS arg may contain one or more of the following bits:
777 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
779 DMGL_PARAMS Function parameters are included.
783 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
784 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
785 cplus_demangle ("foo__1Ai", 0) => "A::foo"
787 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
788 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
789 cplus_demangle ("foo__1Afe", 0) => "A::foo"
791 Note that any leading underscores, or other such characters prepended by
792 the compilation system, are presumed to have already been stripped from
796 cplus_demangle (mangled
, options
)
801 struct work_stuff work
[1];
802 memset ((char *) work
, 0, sizeof (work
));
803 work
-> options
= options
;
804 if ((work
-> options
& DMGL_STYLE_MASK
) == 0)
805 work
-> options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
807 ret
= internal_cplus_demangle (work
, mangled
);
808 squangle_mop_up (work
);
813 /* This function performs most of what cplus_demangle use to do, but
814 to be able to demangle a name with a B, K or n code, we need to
815 have a longer term memory of what types have been seen. The original
816 now intializes and cleans up the squangle code info, while internal
817 calls go directly to this routine to avoid resetting that info. */
820 internal_cplus_demangle (work
, mangled
)
821 struct work_stuff
*work
;
827 char *demangled
= NULL
;
829 s1
= work
->constructor
;
830 s2
= work
->destructor
;
831 s3
= work
->static_type
;
832 s4
= work
->type_quals
;
833 work
->constructor
= work
->destructor
= 0;
834 work
->type_quals
= TYPE_UNQUALIFIED
;
835 work
->dllimported
= 0;
837 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
841 /* First check to see if gnu style demangling is active and if the
842 string to be demangled contains a CPLUS_MARKER. If so, attempt to
843 recognize one of the gnu special forms rather than looking for a
844 standard prefix. In particular, don't worry about whether there
845 is a "__" string in the mangled string. Consider "_$_5__foo" for
848 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
850 success
= gnu_special (work
, &mangled
, &decl
);
854 success
= demangle_prefix (work
, &mangled
, &decl
);
856 if (success
&& (*mangled
!= '\0'))
858 success
= demangle_signature (work
, &mangled
, &decl
);
860 if (work
->constructor
== 2)
862 string_prepend (&decl
, "global constructors keyed to ");
863 work
->constructor
= 0;
865 else if (work
->destructor
== 2)
867 string_prepend (&decl
, "global destructors keyed to ");
868 work
->destructor
= 0;
870 else if (work
->dllimported
== 1)
872 string_prepend (&decl
, "import stub for ");
873 work
->dllimported
= 0;
875 demangled
= mop_up (work
, &decl
, success
);
877 work
->constructor
= s1
;
878 work
->destructor
= s2
;
879 work
->static_type
= s3
;
880 work
->type_quals
= s4
;
885 /* Clear out and squangling related storage */
887 squangle_mop_up (work
)
888 struct work_stuff
*work
;
890 /* clean up the B and K type mangling types. */
891 forget_B_and_K_types (work
);
892 if (work
-> btypevec
!= NULL
)
894 free ((char *) work
-> btypevec
);
896 if (work
-> ktypevec
!= NULL
)
898 free ((char *) work
-> ktypevec
);
902 /* Clear out any mangled storage */
905 mop_up (work
, declp
, success
)
906 struct work_stuff
*work
;
910 char *demangled
= NULL
;
912 /* Discard the remembered types, if any. */
915 if (work
-> typevec
!= NULL
)
917 free ((char *) work
-> typevec
);
918 work
-> typevec
= NULL
;
919 work
-> typevec_size
= 0;
921 if (work
->tmpl_argvec
)
925 for (i
= 0; i
< work
->ntmpl_args
; i
++)
926 if (work
->tmpl_argvec
[i
])
927 free ((char*) work
->tmpl_argvec
[i
]);
929 free ((char*) work
->tmpl_argvec
);
930 work
->tmpl_argvec
= NULL
;
932 if (work
->previous_argument
)
934 string_delete (work
->previous_argument
);
935 free ((char*) work
->previous_argument
);
936 work
->previous_argument
= NULL
;
939 /* If demangling was successful, ensure that the demangled string is null
940 terminated and return it. Otherwise, free the demangling decl. */
944 string_delete (declp
);
948 string_appendn (declp
, "", 1);
949 demangled
= declp
-> b
;
958 demangle_signature -- demangle the signature part of a mangled name
963 demangle_signature (struct work_stuff *work, const char **mangled,
968 Consume and demangle the signature portion of the mangled name.
970 DECLP is the string where demangled output is being built. At
971 entry it contains the demangled root name from the mangled name
972 prefix. I.E. either a demangled operator name or the root function
973 name. In some special cases, it may contain nothing.
975 *MANGLED points to the current unconsumed location in the mangled
976 name. As tokens are consumed and demangling is performed, the
977 pointer is updated to continuously point at the next token to
980 Demangling GNU style mangled names is nasty because there is no
981 explicit token that marks the start of the outermost function
985 demangle_signature (work
, mangled
, declp
)
986 struct work_stuff
*work
;
987 const char **mangled
;
993 int expect_return_type
= 0;
994 const char *oldmangled
= NULL
;
998 while (success
&& (**mangled
!= '\0'))
1003 oldmangled
= *mangled
;
1004 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1006 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1007 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1013 oldmangled
= *mangled
;
1014 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1015 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1023 /* Static member function */
1024 if (oldmangled
== NULL
)
1026 oldmangled
= *mangled
;
1029 work
-> static_type
= 1;
1035 work
->type_quals
|= code_for_qualifier (**mangled
);
1037 /* a qualified member function */
1038 if (oldmangled
== NULL
)
1039 oldmangled
= *mangled
;
1044 /* Local class name follows after "Lnnn_" */
1047 while (**mangled
&& (**mangled
!= '_'))
1058 case '0': case '1': case '2': case '3': case '4':
1059 case '5': case '6': case '7': case '8': case '9':
1060 if (oldmangled
== NULL
)
1062 oldmangled
= *mangled
;
1064 work
->temp_start
= -1; /* uppermost call to demangle_class */
1065 success
= demangle_class (work
, mangled
, declp
);
1068 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1070 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1072 /* EDG and others will have the "F", so we let the loop cycle
1073 if we are looking at one. */
1074 if (**mangled
!= 'F')
1083 success
= do_type (work
, mangled
, &s
);
1086 string_append (&s
, SCOPE_STRING (work
));
1087 string_prepends (declp
, &s
);
1096 /* ARM/HP style demangling includes a specific 'F' character after
1097 the class name. For GNU style, it is just implied. So we can
1098 safely just consume any 'F' at this point and be compatible
1099 with either style. */
1105 /* For lucid/ARM/HP style we have to forget any types we might
1106 have remembered up to this point, since they were not argument
1107 types. GNU style considers all types seen as available for
1108 back references. See comment in demangle_args() */
1110 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1112 forget_types (work
);
1114 success
= demangle_args (work
, mangled
, declp
);
1115 /* After picking off the function args, we expect to either
1116 find the function return type (preceded by an '_') or the
1117 end of the string. */
1118 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1121 /* At this level, we do not care about the return type. */
1122 success
= do_type (work
, mangled
, &tname
);
1123 string_delete (&tname
);
1130 string_init(&trawname
);
1131 string_init(&tname
);
1132 if (oldmangled
== NULL
)
1134 oldmangled
= *mangled
;
1136 success
= demangle_template (work
, mangled
, &tname
,
1140 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1142 string_append (&tname
, SCOPE_STRING (work
));
1144 string_prepends(declp
, &tname
);
1145 if (work
-> destructor
& 1)
1147 string_prepend (&trawname
, "~");
1148 string_appends (declp
, &trawname
);
1149 work
->destructor
-= 1;
1151 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1153 string_appends (declp
, &trawname
);
1154 work
->constructor
-= 1;
1156 string_delete(&trawname
);
1157 string_delete(&tname
);
1163 if (GNU_DEMANGLING
&& expect_return_type
)
1165 /* Read the return type. */
1167 string_init (&return_type
);
1170 success
= do_type (work
, mangled
, &return_type
);
1171 APPEND_BLANK (&return_type
);
1173 string_prepends (declp
, &return_type
);
1174 string_delete (&return_type
);
1178 /* At the outermost level, we cannot have a return type specified,
1179 so if we run into another '_' at this point we are dealing with
1180 a mangled name that is either bogus, or has been mangled by
1181 some algorithm we don't know how to deal with. So just
1182 reject the entire demangling. */
1183 /* However, "_nnn" is an expected suffix for alternate entry point
1184 numbered nnn for a function, with HP aCC, so skip over that
1185 without reporting failure. pai/1997-09-04 */
1189 while (**mangled
&& isdigit ((unsigned char)**mangled
))
1199 /* A G++ template function. Read the template arguments. */
1200 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1202 if (!(work
->constructor
& 1))
1203 expect_return_type
= 1;
1212 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1214 /* Assume we have stumbled onto the first outermost function
1215 argument token, and start processing args. */
1217 success
= demangle_args (work
, mangled
, declp
);
1221 /* Non-GNU demanglers use a specific token to mark the start
1222 of the outermost function argument tokens. Typically 'F',
1223 for ARM/HP-demangling, for example. So if we find something
1224 we are not prepared for, it must be an error. */
1230 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1233 if (success
&& expect_func
)
1236 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1238 forget_types (work
);
1240 success
= demangle_args (work
, mangled
, declp
);
1241 /* Since template include the mangling of their return types,
1242 we must set expect_func to 0 so that we don't try do
1243 demangle more arguments the next time we get here. */
1248 if (success
&& !func_done
)
1250 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1252 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1253 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1254 first case, and need to ensure that the '(void)' gets added to
1255 the current declp. Note that with ARM/HP, the first case
1256 represents the name of a static data member 'foo::bar',
1257 which is in the current declp, so we leave it alone. */
1258 success
= demangle_args (work
, mangled
, declp
);
1261 if (success
&& PRINT_ARG_TYPES
)
1263 if (work
->static_type
)
1264 string_append (declp
, " static");
1265 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1267 APPEND_BLANK (declp
);
1268 string_append (declp
, qualifier_string (work
->type_quals
));
1278 demangle_method_args (work
, mangled
, declp
)
1279 struct work_stuff
*work
;
1280 const char **mangled
;
1285 if (work
-> static_type
)
1287 string_append (declp
, *mangled
+ 1);
1288 *mangled
+= strlen (*mangled
);
1293 success
= demangle_args (work
, mangled
, declp
);
1301 demangle_template_template_parm (work
, mangled
, tname
)
1302 struct work_stuff
*work
;
1303 const char **mangled
;
1312 string_append (tname
, "template <");
1313 /* get size of template parameter list */
1314 if (get_count (mangled
, &r
))
1316 for (i
= 0; i
< r
; i
++)
1320 string_append (tname
, ", ");
1323 /* Z for type parameters */
1324 if (**mangled
== 'Z')
1327 string_append (tname
, "class");
1329 /* z for template parameters */
1330 else if (**mangled
== 'z')
1334 demangle_template_template_parm (work
, mangled
, tname
);
1342 /* temp is initialized in do_type */
1343 success
= do_type (work
, mangled
, &temp
);
1346 string_appends (tname
, &temp
);
1348 string_delete(&temp
);
1358 if (tname
->p
[-1] == '>')
1359 string_append (tname
, " ");
1360 string_append (tname
, "> class");
1365 demangle_expression (work
, mangled
, s
, tk
)
1366 struct work_stuff
*work
;
1367 const char** mangled
;
1371 int need_operator
= 0;
1375 string_appendn (s
, "(", 1);
1377 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1386 len
= strlen (*mangled
);
1389 i
< sizeof (optable
) / sizeof (optable
[0]);
1392 size_t l
= strlen (optable
[i
].in
);
1395 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1397 string_appendn (s
, " ", 1);
1398 string_append (s
, optable
[i
].out
);
1399 string_appendn (s
, " ", 1);
1412 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1415 if (**mangled
!= 'W')
1419 string_appendn (s
, ")", 1);
1427 demangle_integral_value (work
, mangled
, s
)
1428 struct work_stuff
*work
;
1429 const char** mangled
;
1434 if (**mangled
== 'E')
1435 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1436 else if (**mangled
== 'Q' || **mangled
== 'K')
1437 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1444 /* Negative numbers are indicated with a leading `m'. */
1445 if (**mangled
== 'm')
1447 string_appendn (s
, "-", 1);
1451 /* Read the rest of the number. */
1452 value
= consume_count_with_underscores (mangled
);
1455 char buf
[INTBUF_SIZE
];
1456 sprintf (buf
, "%d", value
);
1457 string_append (s
, buf
);
1459 /* If the next character is an underscore, skip it. */
1460 if (**mangled
== '_')
1471 /* Demangle the real value in MANGLED. */
1474 demangle_real_value (work
, mangled
, s
)
1475 struct work_stuff
*work
;
1476 const char **mangled
;
1479 if (**mangled
== 'E')
1480 return demangle_expression (work
, mangled
, s
, tk_real
);
1482 if (**mangled
== 'm')
1484 string_appendn (s
, "-", 1);
1487 while (isdigit ((unsigned char)**mangled
))
1489 string_appendn (s
, *mangled
, 1);
1492 if (**mangled
== '.') /* fraction */
1494 string_appendn (s
, ".", 1);
1496 while (isdigit ((unsigned char)**mangled
))
1498 string_appendn (s
, *mangled
, 1);
1502 if (**mangled
== 'e') /* exponent */
1504 string_appendn (s
, "e", 1);
1506 while (isdigit ((unsigned char)**mangled
))
1508 string_appendn (s
, *mangled
, 1);
1517 demangle_template_value_parm (work
, mangled
, s
, tk
)
1518 struct work_stuff
*work
;
1519 const char **mangled
;
1525 if (**mangled
== 'Y')
1527 /* The next argument is a template parameter. */
1531 idx
= consume_count_with_underscores (mangled
);
1533 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1534 || consume_count_with_underscores (mangled
) == -1)
1536 if (work
->tmpl_argvec
)
1537 string_append (s
, work
->tmpl_argvec
[idx
]);
1539 string_append_template_idx (s
, idx
);
1541 else if (tk
== tk_integral
)
1542 success
= demangle_integral_value (work
, mangled
, s
);
1543 else if (tk
== tk_char
)
1547 if (**mangled
== 'm')
1549 string_appendn (s
, "-", 1);
1552 string_appendn (s
, "'", 1);
1553 val
= consume_count(mangled
);
1560 string_appendn (s
, &tmp
[0], 1);
1561 string_appendn (s
, "'", 1);
1564 else if (tk
== tk_bool
)
1566 int val
= consume_count (mangled
);
1568 string_appendn (s
, "false", 5);
1570 string_appendn (s
, "true", 4);
1574 else if (tk
== tk_real
)
1575 success
= demangle_real_value (work
, mangled
, s
);
1576 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1578 if (**mangled
== 'Q')
1579 success
= demangle_qualified (work
, mangled
, s
,
1584 int symbol_len
= consume_count (mangled
);
1585 if (symbol_len
== -1)
1587 if (symbol_len
== 0)
1588 string_appendn (s
, "0", 1);
1591 char *p
= xmalloc (symbol_len
+ 1), *q
;
1592 strncpy (p
, *mangled
, symbol_len
);
1593 p
[symbol_len
] = '\0';
1594 /* We use cplus_demangle here, rather than
1595 internal_cplus_demangle, because the name of the entity
1596 mangled here does not make use of any of the squangling
1597 or type-code information we have built up thus far; it is
1598 mangled independently. */
1599 q
= cplus_demangle (p
, work
->options
);
1600 if (tk
== tk_pointer
)
1601 string_appendn (s
, "&", 1);
1602 /* FIXME: Pointer-to-member constants should get a
1603 qualifying class name here. */
1606 string_append (s
, q
);
1610 string_append (s
, p
);
1613 *mangled
+= symbol_len
;
1620 /* Demangle the template name in MANGLED. The full name of the
1621 template (e.g., S<int>) is placed in TNAME. The name without the
1622 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1623 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1624 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1625 the tmeplate is remembered in the list of back-referenceable
1629 demangle_template (work
, mangled
, tname
, trawname
, is_type
, remember
)
1630 struct work_stuff
*work
;
1631 const char **mangled
;
1642 int is_java_array
= 0;
1650 bindex
= register_Btype (work
);
1652 /* get template name */
1653 if (**mangled
== 'z')
1659 idx
= consume_count_with_underscores (mangled
);
1661 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1662 || consume_count_with_underscores (mangled
) == -1)
1665 if (work
->tmpl_argvec
)
1667 string_append (tname
, work
->tmpl_argvec
[idx
]);
1669 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1673 string_append_template_idx (tname
, idx
);
1675 string_append_template_idx (trawname
, idx
);
1680 if ((r
= consume_count (mangled
)) <= 0
1681 || (int) strlen (*mangled
) < r
)
1685 is_java_array
= (work
-> options
& DMGL_JAVA
)
1686 && strncmp (*mangled
, "JArray1Z", 8) == 0;
1687 if (! is_java_array
)
1689 string_appendn (tname
, *mangled
, r
);
1692 string_appendn (trawname
, *mangled
, r
);
1697 string_append (tname
, "<");
1698 /* get size of template parameter list */
1699 if (!get_count (mangled
, &r
))
1705 /* Create an array for saving the template argument values. */
1706 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
1707 work
->ntmpl_args
= r
;
1708 for (i
= 0; i
< r
; i
++)
1709 work
->tmpl_argvec
[i
] = 0;
1711 for (i
= 0; i
< r
; i
++)
1715 string_append (tname
, ", ");
1717 /* Z for type parameters */
1718 if (**mangled
== 'Z')
1721 /* temp is initialized in do_type */
1722 success
= do_type (work
, mangled
, &temp
);
1725 string_appends (tname
, &temp
);
1729 /* Save the template argument. */
1730 int len
= temp
.p
- temp
.b
;
1731 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1732 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
1733 work
->tmpl_argvec
[i
][len
] = '\0';
1736 string_delete(&temp
);
1742 /* z for template parameters */
1743 else if (**mangled
== 'z')
1747 success
= demangle_template_template_parm (work
, mangled
, tname
);
1750 && (r2
= consume_count (mangled
)) > 0
1751 && (int) strlen (*mangled
) >= r2
)
1753 string_append (tname
, " ");
1754 string_appendn (tname
, *mangled
, r2
);
1757 /* Save the template argument. */
1759 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1760 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
1761 work
->tmpl_argvec
[i
][len
] = '\0';
1775 /* otherwise, value parameter */
1777 /* temp is initialized in do_type */
1778 success
= do_type (work
, mangled
, &temp
);
1779 string_delete(&temp
);
1791 success
= demangle_template_value_parm (work
, mangled
, s
,
1792 (type_kind_t
) success
);
1804 int len
= s
->p
- s
->b
;
1805 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1806 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
1807 work
->tmpl_argvec
[i
][len
] = '\0';
1809 string_appends (tname
, s
);
1817 string_append (tname
, "[]");
1821 if (tname
->p
[-1] == '>')
1822 string_append (tname
, " ");
1823 string_append (tname
, ">");
1826 if (is_type
&& remember
)
1827 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
1830 if (work -> static_type)
1832 string_append (declp, *mangled + 1);
1833 *mangled += strlen (*mangled);
1838 success = demangle_args (work, mangled, declp);
1846 arm_pt (work
, mangled
, n
, anchor
, args
)
1847 struct work_stuff
*work
;
1848 const char *mangled
;
1850 const char **anchor
, **args
;
1852 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1853 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1854 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= mystrstr (mangled
, "__pt__")))
1857 *args
= *anchor
+ 6;
1858 len
= consume_count (args
);
1861 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1867 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
1869 if ((*anchor
= mystrstr (mangled
, "__tm__"))
1870 || (*anchor
= mystrstr (mangled
, "__ps__"))
1871 || (*anchor
= mystrstr (mangled
, "__pt__")))
1874 *args
= *anchor
+ 6;
1875 len
= consume_count (args
);
1878 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1884 else if ((*anchor
= mystrstr (mangled
, "__S")))
1887 *args
= *anchor
+ 3;
1888 len
= consume_count (args
);
1891 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1903 demangle_arm_hp_template (work
, mangled
, n
, declp
)
1904 struct work_stuff
*work
;
1905 const char **mangled
;
1911 const char *e
= *mangled
+ n
;
1914 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1916 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
1918 char *start_spec_args
= NULL
;
1920 /* First check for and omit template specialization pseudo-arguments,
1921 such as in "Spec<#1,#1.*>" */
1922 start_spec_args
= strchr (*mangled
, '<');
1923 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
1924 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
1926 string_appendn (declp
, *mangled
, n
);
1927 (*mangled
) += n
+ 1;
1929 if (work
->temp_start
== -1) /* non-recursive call */
1930 work
->temp_start
= declp
->p
- declp
->b
;
1931 string_append (declp
, "<");
1934 string_clear (&arg
);
1938 /* 'T' signals a type parameter */
1940 if (!do_type (work
, mangled
, &arg
))
1941 goto hpacc_template_args_done
;
1946 /* 'U' or 'S' signals an integral value */
1947 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
1948 goto hpacc_template_args_done
;
1952 /* 'A' signals a named constant expression (literal) */
1953 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
1954 goto hpacc_template_args_done
;
1958 /* Today, 1997-09-03, we have only the above types
1959 of template parameters */
1960 /* FIXME: maybe this should fail and return null */
1961 goto hpacc_template_args_done
;
1963 string_appends (declp
, &arg
);
1964 /* Check if we're at the end of template args.
1965 0 if at end of static member of template class,
1966 _ if done with template args for a function */
1967 if ((**mangled
== '\000') || (**mangled
== '_'))
1970 string_append (declp
, ",");
1972 hpacc_template_args_done
:
1973 string_append (declp
, ">");
1974 string_delete (&arg
);
1975 if (**mangled
== '_')
1979 /* ARM template? (Also handles HP cfront extensions) */
1980 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
1985 string_appendn (declp
, *mangled
, p
- *mangled
);
1986 if (work
->temp_start
== -1) /* non-recursive call */
1987 work
->temp_start
= declp
->p
- declp
->b
;
1988 string_append (declp
, "<");
1989 /* should do error checking here */
1991 string_clear (&arg
);
1993 /* Check for type or literal here */
1996 /* HP cfront extensions to ARM for template args */
1997 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1998 /* FIXME: We handle only numeric literals for HP cfront */
2000 /* A typed constant value follows */
2002 if (!do_type (work
, &args
, &type_str
))
2003 goto cfront_template_args_done
;
2004 string_append (&arg
, "(");
2005 string_appends (&arg
, &type_str
);
2006 string_append (&arg
, ")");
2008 goto cfront_template_args_done
;
2010 /* Now snarf a literal value following 'L' */
2011 if (!snarf_numeric_literal (&args
, &arg
))
2012 goto cfront_template_args_done
;
2016 /* Snarf a literal following 'L' */
2018 if (!snarf_numeric_literal (&args
, &arg
))
2019 goto cfront_template_args_done
;
2022 /* Not handling other HP cfront stuff */
2023 if (!do_type (work
, &args
, &arg
))
2024 goto cfront_template_args_done
;
2026 string_appends (declp
, &arg
);
2027 string_append (declp
, ",");
2029 cfront_template_args_done
:
2030 string_delete (&arg
);
2032 --declp
->p
; /* remove extra comma */
2033 string_append (declp
, ">");
2035 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2036 && (*mangled
)[9] == 'N'
2037 && (*mangled
)[8] == (*mangled
)[10]
2038 && strchr (cplus_markers
, (*mangled
)[8]))
2040 /* A member of the anonymous namespace. */
2041 string_append (declp
, "{anonymous}");
2045 if (work
->temp_start
== -1) /* non-recursive call only */
2046 work
->temp_start
= 0; /* disable in recursive calls */
2047 string_appendn (declp
, *mangled
, n
);
2052 /* Extract a class name, possibly a template with arguments, from the
2053 mangled string; qualifiers, local class indicators, etc. have
2054 already been dealt with */
2057 demangle_class_name (work
, mangled
, declp
)
2058 struct work_stuff
*work
;
2059 const char **mangled
;
2065 n
= consume_count (mangled
);
2068 if ((int) strlen (*mangled
) >= n
)
2070 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2081 demangle_class -- demangle a mangled class sequence
2086 demangle_class (struct work_stuff *work, const char **mangled,
2091 DECLP points to the buffer into which demangling is being done.
2093 *MANGLED points to the current token to be demangled. On input,
2094 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2095 On exit, it points to the next token after the mangled class on
2096 success, or the first unconsumed token on failure.
2098 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2099 we are demangling a constructor or destructor. In this case
2100 we prepend "class::class" or "class::~class" to DECLP.
2102 Otherwise, we prepend "class::" to the current DECLP.
2104 Reset the constructor/destructor flags once they have been
2105 "consumed". This allows demangle_class to be called later during
2106 the same demangling, to do normal class demangling.
2108 Returns 1 if demangling is successful, 0 otherwise.
2113 demangle_class (work
, mangled
, declp
)
2114 struct work_stuff
*work
;
2115 const char **mangled
;
2121 char *save_class_name_end
= 0;
2123 string_init (&class_name
);
2124 btype
= register_Btype (work
);
2125 if (demangle_class_name (work
, mangled
, &class_name
))
2127 save_class_name_end
= class_name
.p
;
2128 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2130 /* adjust so we don't include template args */
2131 if (work
->temp_start
&& (work
->temp_start
!= -1))
2133 class_name
.p
= class_name
.b
+ work
->temp_start
;
2135 string_prepends (declp
, &class_name
);
2136 if (work
-> destructor
& 1)
2138 string_prepend (declp
, "~");
2139 work
-> destructor
-= 1;
2143 work
-> constructor
-= 1;
2146 class_name
.p
= save_class_name_end
;
2147 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2148 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2149 string_prepend (declp
, SCOPE_STRING (work
));
2150 string_prepends (declp
, &class_name
);
2153 string_delete (&class_name
);
2161 demangle_prefix -- consume the mangled name prefix and find signature
2166 demangle_prefix (struct work_stuff *work, const char **mangled,
2171 Consume and demangle the prefix of the mangled name.
2173 DECLP points to the string buffer into which demangled output is
2174 placed. On entry, the buffer is empty. On exit it contains
2175 the root function name, the demangled operator name, or in some
2176 special cases either nothing or the completely demangled result.
2178 MANGLED points to the current pointer into the mangled name. As each
2179 token of the mangled name is consumed, it is updated. Upon entry
2180 the current mangled name pointer points to the first character of
2181 the mangled name. Upon exit, it should point to the first character
2182 of the signature if demangling was successful, or to the first
2183 unconsumed character if demangling of the prefix was unsuccessful.
2185 Returns 1 on success, 0 otherwise.
2189 demangle_prefix (work
, mangled
, declp
)
2190 struct work_stuff
*work
;
2191 const char **mangled
;
2198 if (strlen(*mangled
) > 6
2199 && (strncmp(*mangled
, "_imp__", 6) == 0
2200 || strncmp(*mangled
, "__imp_", 6) == 0))
2202 /* it's a symbol imported from a PE dynamic library. Check for both
2203 new style prefix _imp__ and legacy __imp_ used by older versions
2206 work
->dllimported
= 1;
2208 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2210 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2211 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2213 if ((*mangled
)[9] == 'D')
2215 /* it's a GNU global destructor to be executed at program exit */
2217 work
->destructor
= 2;
2218 if (gnu_special (work
, mangled
, declp
))
2221 else if ((*mangled
)[9] == 'I')
2223 /* it's a GNU global constructor to be executed at program init */
2225 work
->constructor
= 2;
2226 if (gnu_special (work
, mangled
, declp
))
2231 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2233 /* it's a ARM global destructor to be executed at program exit */
2235 work
->destructor
= 2;
2237 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2239 /* it's a ARM global constructor to be executed at program initial */
2241 work
->constructor
= 2;
2244 /* This block of code is a reduction in strength time optimization
2246 scan = mystrstr (*mangled, "__"); */
2252 scan
= strchr (scan
, '_');
2253 } while (scan
!= NULL
&& *++scan
!= '_');
2255 if (scan
!= NULL
) --scan
;
2260 /* We found a sequence of two or more '_', ensure that we start at
2261 the last pair in the sequence. */
2262 i
= strspn (scan
, "_");
2273 else if (work
-> static_type
)
2275 if (!isdigit ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2280 else if ((scan
== *mangled
)
2281 && (isdigit ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2282 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2284 /* The ARM says nothing about the mangling of local variables.
2285 But cfront mangles local variables by prepending __<nesting_level>
2286 to them. As an extension to ARM demangling we handle this case. */
2287 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2288 && isdigit ((unsigned char)scan
[2]))
2290 *mangled
= scan
+ 2;
2291 consume_count (mangled
);
2292 string_append (declp
, *mangled
);
2293 *mangled
+= strlen (*mangled
);
2298 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2299 names like __Q2_3foo3bar for nested type names. So don't accept
2300 this style of constructor for cfront demangling. A GNU
2301 style member-template constructor starts with 'H'. */
2302 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2303 work
-> constructor
+= 1;
2304 *mangled
= scan
+ 2;
2307 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2309 /* Cfront-style parameterized type. Handled later as a signature. */
2313 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2315 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2316 || (scan
[2] == 'p' && scan
[3] == 's')
2317 || (scan
[2] == 'p' && scan
[3] == 't')))
2319 /* EDG-style parameterized type. Handled later as a signature. */
2323 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2325 else if ((scan
== *mangled
) && !isdigit ((unsigned char)scan
[2])
2326 && (scan
[2] != 't'))
2328 /* Mangled name starts with "__". Skip over any leading '_' characters,
2329 then find the next "__" that separates the prefix from the signature.
2331 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2332 || (arm_special (mangled
, declp
) == 0))
2334 while (*scan
== '_')
2338 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2340 /* No separator (I.E. "__not_mangled"), or empty signature
2341 (I.E. "__not_mangled_either__") */
2348 /* Look for the LAST occurrence of __, allowing names to
2349 have the '__' sequence embedded in them. */
2350 if (!(ARM_DEMANGLING
|| HP_DEMANGLING
))
2352 while ((tmp
= mystrstr (scan
+ 2, "__")) != NULL
)
2355 if (*(scan
+ 2) == '\0')
2358 demangle_function_name (work
, mangled
, declp
, scan
);
2362 else if (*(scan
+ 2) != '\0')
2364 /* Mangled name does not start with "__" but does have one somewhere
2365 in there with non empty stuff after it. Looks like a global
2367 demangle_function_name (work
, mangled
, declp
, scan
);
2371 /* Doesn't look like a mangled name */
2375 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2377 string_append (declp
, *mangled
);
2378 *mangled
+= strlen (*mangled
);
2388 gnu_special -- special handling of gnu mangled strings
2393 gnu_special (struct work_stuff *work, const char **mangled,
2399 Process some special GNU style mangling forms that don't fit
2400 the normal pattern. For example:
2402 _$_3foo (destructor for class foo)
2403 _vt$foo (foo virtual table)
2404 _vt$foo$bar (foo::bar virtual table)
2405 __vt_foo (foo virtual table, new style with thunks)
2406 _3foo$varname (static data member)
2407 _Q22rs2tu$vw (static data member)
2408 __t6vector1Zii (constructor with template)
2409 __thunk_4__$_7ostream (virtual function thunk)
2413 gnu_special (work
, mangled
, declp
)
2414 struct work_stuff
*work
;
2415 const char **mangled
;
2422 if ((*mangled
)[0] == '_'
2423 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2424 && (*mangled
)[2] == '_')
2426 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2428 work
-> destructor
+= 1;
2430 else if ((*mangled
)[0] == '_'
2431 && (((*mangled
)[1] == '_'
2432 && (*mangled
)[2] == 'v'
2433 && (*mangled
)[3] == 't'
2434 && (*mangled
)[4] == '_')
2435 || ((*mangled
)[1] == 'v'
2436 && (*mangled
)[2] == 't'
2437 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2439 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2440 and create the decl. Note that we consume the entire mangled
2441 input string, which means that demangle_signature has no work
2443 if ((*mangled
)[2] == 'v')
2444 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2446 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2447 while (**mangled
!= '\0')
2453 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2456 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2460 if (isdigit((unsigned char)*mangled
[0]))
2462 n
= consume_count(mangled
);
2463 /* We may be seeing a too-large size, or else a
2464 ".<digits>" indicating a static local symbol. In
2465 any case, declare victory and move on; *don't* try
2466 to use n to allocate. */
2467 if (n
> (int) strlen (*mangled
))
2475 n
= strcspn (*mangled
, cplus_markers
);
2477 string_appendn (declp
, *mangled
, n
);
2481 p
= strpbrk (*mangled
, cplus_markers
);
2482 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2486 string_append (declp
, SCOPE_STRING (work
));
2497 string_append (declp
, " virtual table");
2499 else if ((*mangled
)[0] == '_'
2500 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2501 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2503 /* static data member, "_3foo$varname" for example */
2509 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2512 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2515 n
= consume_count (mangled
);
2516 if (n
< 0 || n
> (long) strlen (*mangled
))
2521 string_appendn (declp
, *mangled
, n
);
2524 if (success
&& (p
== *mangled
))
2526 /* Consumed everything up to the cplus_marker, append the
2529 string_append (declp
, SCOPE_STRING (work
));
2530 n
= strlen (*mangled
);
2531 string_appendn (declp
, *mangled
, n
);
2539 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2544 delta
= consume_count (mangled
);
2549 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2554 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2555 string_append (declp
, buf
);
2556 string_append (declp
, method
);
2558 n
= strlen (*mangled
);
2567 else if (strncmp (*mangled
, "__t", 3) == 0
2568 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2570 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2576 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2579 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2582 success
= demangle_fund_type (work
, mangled
, declp
);
2585 if (success
&& **mangled
!= '\0')
2588 string_append (declp
, p
);
2598 recursively_demangle(work
, mangled
, result
, namelength
)
2599 struct work_stuff
*work
;
2600 const char **mangled
;
2604 char * recurse
= (char *)NULL
;
2605 char * recurse_dem
= (char *)NULL
;
2607 recurse
= (char *) xmalloc (namelength
+ 1);
2608 memcpy (recurse
, *mangled
, namelength
);
2609 recurse
[namelength
] = '\000';
2611 recurse_dem
= cplus_demangle (recurse
, work
->options
);
2615 string_append (result
, recurse_dem
);
2620 string_appendn (result
, *mangled
, namelength
);
2623 *mangled
+= namelength
;
2630 arm_special -- special handling of ARM/lucid mangled strings
2635 arm_special (const char **mangled,
2641 Process some special ARM style mangling forms that don't fit
2642 the normal pattern. For example:
2644 __vtbl__3foo (foo virtual table)
2645 __vtbl__3foo__3bar (bar::foo virtual table)
2650 arm_special (mangled
, declp
)
2651 const char **mangled
;
2658 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
2660 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2661 and create the decl. Note that we consume the entire mangled
2662 input string, which means that demangle_signature has no work
2664 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
2665 while (*scan
!= '\0') /* first check it can be demangled */
2667 n
= consume_count (&scan
);
2670 return (0); /* no good */
2673 if (scan
[0] == '_' && scan
[1] == '_')
2678 (*mangled
) += ARM_VTABLE_STRLEN
;
2679 while (**mangled
!= '\0')
2681 n
= consume_count (mangled
);
2683 || n
> (long) strlen (*mangled
))
2685 string_prependn (declp
, *mangled
, n
);
2687 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
2689 string_prepend (declp
, "::");
2693 string_append (declp
, " virtual table");
2706 demangle_qualified -- demangle 'Q' qualified name strings
2711 demangle_qualified (struct work_stuff *, const char *mangled,
2712 string *result, int isfuncname, int append);
2716 Demangle a qualified name, such as "Q25Outer5Inner" which is
2717 the mangled form of "Outer::Inner". The demangled output is
2718 prepended or appended to the result string according to the
2719 state of the append flag.
2721 If isfuncname is nonzero, then the qualified name we are building
2722 is going to be used as a member function name, so if it is a
2723 constructor or destructor function, append an appropriate
2724 constructor or destructor name. I.E. for the above example,
2725 the result for use as a constructor is "Outer::Inner::Inner"
2726 and the result for use as a destructor is "Outer::Inner::~Inner".
2730 Numeric conversion is ASCII dependent (FIXME).
2735 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
2736 struct work_stuff
*work
;
2737 const char **mangled
;
2747 int bindex
= register_Btype (work
);
2749 /* We only make use of ISFUNCNAME if the entity is a constructor or
2751 isfuncname
= (isfuncname
2752 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
2754 string_init (&temp
);
2755 string_init (&last_name
);
2757 if ((*mangled
)[0] == 'K')
2759 /* Squangling qualified name reuse */
2762 idx
= consume_count_with_underscores (mangled
);
2763 if (idx
== -1 || idx
>= work
-> numk
)
2766 string_append (&temp
, work
-> ktypevec
[idx
]);
2769 switch ((*mangled
)[1])
2772 /* GNU mangled name with more than 9 classes. The count is preceded
2773 by an underscore (to distinguish it from the <= 9 case) and followed
2774 by an underscore. */
2776 qualifiers
= consume_count_with_underscores (mangled
);
2777 if (qualifiers
== -1)
2790 /* The count is in a single digit. */
2791 num
[0] = (*mangled
)[1];
2793 qualifiers
= atoi (num
);
2795 /* If there is an underscore after the digit, skip it. This is
2796 said to be for ARM-qualified names, but the ARM makes no
2797 mention of such an underscore. Perhaps cfront uses one. */
2798 if ((*mangled
)[2] == '_')
2813 /* Pick off the names and collect them in the temp buffer in the order
2814 in which they are found, separated by '::'. */
2816 while (qualifiers
-- > 0)
2819 string_clear (&last_name
);
2821 if (*mangled
[0] == '_')
2824 if (*mangled
[0] == 't')
2826 /* Here we always append to TEMP since we will want to use
2827 the template name without the template parameters as a
2828 constructor or destructor name. The appropriate
2829 (parameter-less) value is returned by demangle_template
2830 in LAST_NAME. We do not remember the template type here,
2831 in order to match the G++ mangling algorithm. */
2832 success
= demangle_template(work
, mangled
, &temp
,
2837 else if (*mangled
[0] == 'K')
2841 idx
= consume_count_with_underscores (mangled
);
2842 if (idx
== -1 || idx
>= work
->numk
)
2845 string_append (&temp
, work
->ktypevec
[idx
]);
2848 if (!success
) break;
2855 /* Now recursively demangle the qualifier
2856 * This is necessary to deal with templates in
2857 * mangling styles like EDG */
2858 namelength
= consume_count (mangled
);
2859 if (namelength
== -1)
2864 recursively_demangle(work
, mangled
, &temp
, namelength
);
2868 success
= do_type (work
, mangled
, &last_name
);
2871 string_appends (&temp
, &last_name
);
2876 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
2879 string_append (&temp
, SCOPE_STRING (work
));
2882 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
2884 /* If we are using the result as a function name, we need to append
2885 the appropriate '::' separated constructor or destructor name.
2886 We do this here because this is the most convenient place, where
2887 we already have a pointer to the name and the length of the name. */
2891 string_append (&temp
, SCOPE_STRING (work
));
2892 if (work
-> destructor
& 1)
2893 string_append (&temp
, "~");
2894 string_appends (&temp
, &last_name
);
2897 /* Now either prepend the temp buffer to the result, or append it,
2898 depending upon the state of the append flag. */
2901 string_appends (result
, &temp
);
2904 if (!STRING_EMPTY (result
))
2905 string_append (&temp
, SCOPE_STRING (work
));
2906 string_prepends (result
, &temp
);
2909 string_delete (&last_name
);
2910 string_delete (&temp
);
2918 get_count -- convert an ascii count to integer, consuming tokens
2923 get_count (const char **type, int *count)
2927 Assume that *type points at a count in a mangled name; set
2928 *count to its value, and set *type to the next character after
2929 the count. There are some weird rules in effect here.
2931 If *type does not point at a string of digits, return zero.
2933 If *type points at a string of digits followed by an
2934 underscore, set *count to their value as an integer, advance
2935 *type to point *after the underscore, and return 1.
2937 If *type points at a string of digits not followed by an
2938 underscore, consume only the first digit. Set *count to its
2939 value as an integer, leave *type pointing after that digit,
2942 The excuse for this odd behavior: in the ARM and HP demangling
2943 styles, a type can be followed by a repeat count of the form
2946 `x' is a single digit specifying how many additional copies
2947 of the type to append to the argument list, and
2949 `y' is one or more digits, specifying the zero-based index of
2950 the first repeated argument in the list. Yes, as you're
2951 unmangling the name you can figure this out yourself, but
2954 So, for example, in `bar__3fooFPiN51', the first argument is a
2955 pointer to an integer (`Pi'), and then the next five arguments
2956 are the same (`N5'), and the first repeat is the function's
2957 second argument (`1').
2961 get_count (type
, count
)
2968 if (!isdigit ((unsigned char)**type
))
2972 *count
= **type
- '0';
2974 if (isdigit ((unsigned char)**type
))
2984 while (isdigit ((unsigned char)*p
));
2995 /* RESULT will be initialised here; it will be freed on failure. The
2996 value returned is really a type_kind_t. */
2999 do_type (work
, mangled
, result
)
3000 struct work_stuff
*work
;
3001 const char **mangled
;
3008 const char *remembered_type
;
3011 type_kind_t tk
= tk_none
;
3013 string_init (&btype
);
3014 string_init (&decl
);
3015 string_init (result
);
3019 while (success
&& !done
)
3025 /* A pointer type */
3029 if (! (work
-> options
& DMGL_JAVA
))
3030 string_prepend (&decl
, "*");
3035 /* A reference type */
3038 string_prepend (&decl
, "&");
3047 if (!STRING_EMPTY (&decl
)
3048 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3050 string_prepend (&decl
, "(");
3051 string_append (&decl
, ")");
3053 string_append (&decl
, "[");
3054 if (**mangled
!= '_')
3055 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3057 if (**mangled
== '_')
3059 string_append (&decl
, "]");
3063 /* A back reference to a previously seen type */
3066 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3072 remembered_type
= work
-> typevec
[n
];
3073 mangled
= &remembered_type
;
3080 if (!STRING_EMPTY (&decl
)
3081 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3083 string_prepend (&decl
, "(");
3084 string_append (&decl
, ")");
3086 /* After picking off the function args, we expect to either find the
3087 function return type (preceded by an '_') or the end of the
3089 if (!demangle_nested_args (work
, mangled
, &decl
)
3090 || (**mangled
!= '_' && **mangled
!= '\0'))
3095 if (success
&& (**mangled
== '_'))
3102 type_quals
= TYPE_UNQUALIFIED
;
3104 member
= **mangled
== 'M';
3107 string_append (&decl
, ")");
3109 /* We don't need to prepend `::' for a qualified name;
3110 demangle_qualified will do that for us. */
3111 if (**mangled
!= 'Q')
3112 string_prepend (&decl
, SCOPE_STRING (work
));
3114 if (isdigit ((unsigned char)**mangled
))
3116 n
= consume_count (mangled
);
3118 || (int) strlen (*mangled
) < n
)
3123 string_prependn (&decl
, *mangled
, n
);
3126 else if (**mangled
== 'X' || **mangled
== 'Y')
3129 do_type (work
, mangled
, &temp
);
3130 string_prepends (&decl
, &temp
);
3132 else if (**mangled
== 't')
3135 string_init (&temp
);
3136 success
= demangle_template (work
, mangled
, &temp
,
3140 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3141 string_clear (&temp
);
3146 else if (**mangled
== 'Q')
3148 success
= demangle_qualified (work
, mangled
, &decl
,
3160 string_prepend (&decl
, "(");
3168 type_quals
|= code_for_qualifier (**mangled
);
3176 if (*(*mangled
)++ != 'F')
3182 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3183 || **mangled
!= '_')
3189 if (! PRINT_ANSI_QUALIFIERS
)
3193 if (type_quals
!= TYPE_UNQUALIFIED
)
3195 APPEND_BLANK (&decl
);
3196 string_append (&decl
, qualifier_string (type_quals
));
3207 if (PRINT_ANSI_QUALIFIERS
)
3209 if (!STRING_EMPTY (&decl
))
3210 string_prepend (&decl
, " ");
3212 string_prepend (&decl
, demangle_qualifier (**mangled
));
3227 if (success
) switch (**mangled
)
3229 /* A qualified name, such as "Outer::Inner". */
3233 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3237 /* A back reference to a previously seen squangled type */
3240 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3243 string_append (result
, work
->btypevec
[n
]);
3248 /* A template parm. We substitute the corresponding argument. */
3253 idx
= consume_count_with_underscores (mangled
);
3256 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3257 || consume_count_with_underscores (mangled
) == -1)
3263 if (work
->tmpl_argvec
)
3264 string_append (result
, work
->tmpl_argvec
[idx
]);
3266 string_append_template_idx (result
, idx
);
3273 success
= demangle_fund_type (work
, mangled
, result
);
3275 tk
= (type_kind_t
) success
;
3281 if (!STRING_EMPTY (&decl
))
3283 string_append (result
, " ");
3284 string_appends (result
, &decl
);
3288 string_delete (result
);
3289 string_delete (&decl
);
3292 /* Assume an integral type, if we're not sure. */
3293 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3298 /* Given a pointer to a type string that represents a fundamental type
3299 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3300 string in which the demangled output is being built in RESULT, and
3301 the WORK structure, decode the types and add them to the result.
3306 "Sl" => "signed long"
3307 "CUs" => "const unsigned short"
3309 The value returned is really a type_kind_t. */
3312 demangle_fund_type (work
, mangled
, result
)
3313 struct work_stuff
*work
;
3314 const char **mangled
;
3322 type_kind_t tk
= tk_integral
;
3324 string_init (&btype
);
3326 /* First pick off any type qualifiers. There can be more than one. */
3335 if (PRINT_ANSI_QUALIFIERS
)
3337 if (!STRING_EMPTY (result
))
3338 string_prepend (result
, " ");
3339 string_prepend (result
, demangle_qualifier (**mangled
));
3345 APPEND_BLANK (result
);
3346 string_append (result
, "unsigned");
3348 case 'S': /* signed char only */
3350 APPEND_BLANK (result
);
3351 string_append (result
, "signed");
3355 APPEND_BLANK (result
);
3356 string_append (result
, "__complex");
3364 /* Now pick off the fundamental type. There can be only one. */
3373 APPEND_BLANK (result
);
3374 string_append (result
, "void");
3378 APPEND_BLANK (result
);
3379 string_append (result
, "long long");
3383 APPEND_BLANK (result
);
3384 string_append (result
, "long");
3388 APPEND_BLANK (result
);
3389 string_append (result
, "int");
3393 APPEND_BLANK (result
);
3394 string_append (result
, "short");
3398 APPEND_BLANK (result
);
3399 string_append (result
, "bool");
3404 APPEND_BLANK (result
);
3405 string_append (result
, "char");
3410 APPEND_BLANK (result
);
3411 string_append (result
, "wchar_t");
3416 APPEND_BLANK (result
);
3417 string_append (result
, "long double");
3422 APPEND_BLANK (result
);
3423 string_append (result
, "double");
3428 APPEND_BLANK (result
);
3429 string_append (result
, "float");
3434 if (!isdigit ((unsigned char)**mangled
))
3441 if (**mangled
== '_')
3446 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3449 if (**mangled
!= '_')
3459 strncpy (buf
, *mangled
, 2);
3461 *mangled
+= min (strlen (*mangled
), 2);
3463 sscanf (buf
, "%x", &dec
);
3464 sprintf (buf
, "int%i_t", dec
);
3465 APPEND_BLANK (result
);
3466 string_append (result
, buf
);
3470 /* An explicit type, such as "6mytype" or "7integer" */
3482 int bindex
= register_Btype (work
);
3484 string_init (&btype
);
3485 if (demangle_class_name (work
, mangled
, &btype
)) {
3486 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3487 APPEND_BLANK (result
);
3488 string_appends (result
, &btype
);
3492 string_delete (&btype
);
3497 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3498 string_appends (result
, &btype
);
3506 return success
? ((int) tk
) : 0;
3510 /* Handle a template's value parameter for HP aCC (extension from ARM)
3511 **mangled points to 'S' or 'U' */
3514 do_hpacc_template_const_value (work
, mangled
, result
)
3515 struct work_stuff
*work ATTRIBUTE_UNUSED
;
3516 const char **mangled
;
3521 if (**mangled
!= 'U' && **mangled
!= 'S')
3524 unsigned_const
= (**mangled
== 'U');
3531 string_append (result
, "-");
3537 /* special case for -2^31 */
3538 string_append (result
, "-2147483648");
3545 /* We have to be looking at an integer now */
3546 if (!(isdigit ((unsigned char)**mangled
)))
3549 /* We only deal with integral values for template
3550 parameters -- so it's OK to look only for digits */
3551 while (isdigit ((unsigned char)**mangled
))
3553 char_str
[0] = **mangled
;
3554 string_append (result
, char_str
);
3559 string_append (result
, "U");
3561 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3562 with L or LL suffixes. pai/1997-09-03 */
3564 return 1; /* success */
3567 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3568 **mangled is pointing to the 'A' */
3571 do_hpacc_template_literal (work
, mangled
, result
)
3572 struct work_stuff
*work
;
3573 const char **mangled
;
3576 int literal_len
= 0;
3580 if (**mangled
!= 'A')
3585 literal_len
= consume_count (mangled
);
3587 if (literal_len
<= 0)
3590 /* Literal parameters are names of arrays, functions, etc. and the
3591 canonical representation uses the address operator */
3592 string_append (result
, "&");
3594 /* Now recursively demangle the literal name */
3595 recurse
= (char *) xmalloc (literal_len
+ 1);
3596 memcpy (recurse
, *mangled
, literal_len
);
3597 recurse
[literal_len
] = '\000';
3599 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3603 string_append (result
, recurse_dem
);
3608 string_appendn (result
, *mangled
, literal_len
);
3610 (*mangled
) += literal_len
;
3617 snarf_numeric_literal (args
, arg
)
3624 string_append (arg
, char_str
);
3627 else if (**args
== '+')
3630 if (!isdigit ((unsigned char)**args
))
3633 while (isdigit ((unsigned char)**args
))
3635 char_str
[0] = **args
;
3636 string_append (arg
, char_str
);
3643 /* Demangle the next argument, given by MANGLED into RESULT, which
3644 *should be an uninitialized* string. It will be initialized here,
3645 and free'd should anything go wrong. */
3648 do_arg (work
, mangled
, result
)
3649 struct work_stuff
*work
;
3650 const char **mangled
;
3653 /* Remember where we started so that we can record the type, for
3654 non-squangling type remembering. */
3655 const char *start
= *mangled
;
3657 string_init (result
);
3659 if (work
->nrepeats
> 0)
3663 if (work
->previous_argument
== 0)
3666 /* We want to reissue the previous type in this argument list. */
3667 string_appends (result
, work
->previous_argument
);
3671 if (**mangled
== 'n')
3673 /* A squangling-style repeat. */
3675 work
->nrepeats
= consume_count(mangled
);
3677 if (work
->nrepeats
<= 0)
3678 /* This was not a repeat count after all. */
3681 if (work
->nrepeats
> 9)
3683 if (**mangled
!= '_')
3684 /* The repeat count should be followed by an '_' in this
3691 /* Now, the repeat is all set up. */
3692 return do_arg (work
, mangled
, result
);
3695 /* Save the result in WORK->previous_argument so that we can find it
3696 if it's repeated. Note that saving START is not good enough: we
3697 do not want to add additional types to the back-referenceable
3698 type vector when processing a repeated type. */
3699 if (work
->previous_argument
)
3700 string_clear (work
->previous_argument
);
3703 work
->previous_argument
= (string
*) xmalloc (sizeof (string
));
3704 string_init (work
->previous_argument
);
3707 if (!do_type (work
, mangled
, work
->previous_argument
))
3710 string_appends (result
, work
->previous_argument
);
3712 remember_type (work
, start
, *mangled
- start
);
3717 remember_type (work
, start
, len
)
3718 struct work_stuff
*work
;
3724 if (work
->forgetting_types
)
3727 if (work
-> ntypes
>= work
-> typevec_size
)
3729 if (work
-> typevec_size
== 0)
3731 work
-> typevec_size
= 3;
3733 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
3737 work
-> typevec_size
*= 2;
3739 = (char **) xrealloc ((char *)work
-> typevec
,
3740 sizeof (char *) * work
-> typevec_size
);
3743 tem
= xmalloc (len
+ 1);
3744 memcpy (tem
, start
, len
);
3746 work
-> typevec
[work
-> ntypes
++] = tem
;
3750 /* Remember a K type class qualifier. */
3752 remember_Ktype (work
, start
, len
)
3753 struct work_stuff
*work
;
3759 if (work
-> numk
>= work
-> ksize
)
3761 if (work
-> ksize
== 0)
3765 = (char **) xmalloc (sizeof (char *) * work
-> ksize
);
3771 = (char **) xrealloc ((char *)work
-> ktypevec
,
3772 sizeof (char *) * work
-> ksize
);
3775 tem
= xmalloc (len
+ 1);
3776 memcpy (tem
, start
, len
);
3778 work
-> ktypevec
[work
-> numk
++] = tem
;
3781 /* Register a B code, and get an index for it. B codes are registered
3782 as they are seen, rather than as they are completed, so map<temp<char> >
3783 registers map<temp<char> > as B0, and temp<char> as B1 */
3786 register_Btype (work
)
3787 struct work_stuff
*work
;
3791 if (work
-> numb
>= work
-> bsize
)
3793 if (work
-> bsize
== 0)
3797 = (char **) xmalloc (sizeof (char *) * work
-> bsize
);
3803 = (char **) xrealloc ((char *)work
-> btypevec
,
3804 sizeof (char *) * work
-> bsize
);
3807 ret
= work
-> numb
++;
3808 work
-> btypevec
[ret
] = NULL
;
3812 /* Store a value into a previously registered B code type. */
3815 remember_Btype (work
, start
, len
, index
)
3816 struct work_stuff
*work
;
3822 tem
= xmalloc (len
+ 1);
3823 memcpy (tem
, start
, len
);
3825 work
-> btypevec
[index
] = tem
;
3828 /* Lose all the info related to B and K type codes. */
3830 forget_B_and_K_types (work
)
3831 struct work_stuff
*work
;
3835 while (work
-> numk
> 0)
3837 i
= --(work
-> numk
);
3838 if (work
-> ktypevec
[i
] != NULL
)
3840 free (work
-> ktypevec
[i
]);
3841 work
-> ktypevec
[i
] = NULL
;
3845 while (work
-> numb
> 0)
3847 i
= --(work
-> numb
);
3848 if (work
-> btypevec
[i
] != NULL
)
3850 free (work
-> btypevec
[i
]);
3851 work
-> btypevec
[i
] = NULL
;
3855 /* Forget the remembered types, but not the type vector itself. */
3859 struct work_stuff
*work
;
3863 while (work
-> ntypes
> 0)
3865 i
= --(work
-> ntypes
);
3866 if (work
-> typevec
[i
] != NULL
)
3868 free (work
-> typevec
[i
]);
3869 work
-> typevec
[i
] = NULL
;
3874 /* Process the argument list part of the signature, after any class spec
3875 has been consumed, as well as the first 'F' character (if any). For
3878 "__als__3fooRT0" => process "RT0"
3879 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3881 DECLP must be already initialised, usually non-empty. It won't be freed
3884 Note that g++ differs significantly from ARM and lucid style mangling
3885 with regards to references to previously seen types. For example, given
3886 the source fragment:
3890 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3893 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3894 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3896 g++ produces the names:
3901 while lcc (and presumably other ARM style compilers as well) produces:
3903 foo__FiR3fooT1T2T1T2
3904 __ct__3fooFiR3fooT1T2T1T2
3906 Note that g++ bases its type numbers starting at zero and counts all
3907 previously seen types, while lucid/ARM bases its type numbers starting
3908 at one and only considers types after it has seen the 'F' character
3909 indicating the start of the function args. For lucid/ARM style, we
3910 account for this difference by discarding any previously seen types when
3911 we see the 'F' character, and subtracting one from the type number
3917 demangle_args (work
, mangled
, declp
)
3918 struct work_stuff
*work
;
3919 const char **mangled
;
3929 if (PRINT_ARG_TYPES
)
3931 string_append (declp
, "(");
3932 if (**mangled
== '\0')
3934 string_append (declp
, "void");
3938 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
3939 || work
->nrepeats
> 0)
3941 if ((**mangled
== 'N') || (**mangled
== 'T'))
3943 temptype
= *(*mangled
)++;
3945 if (temptype
== 'N')
3947 if (!get_count (mangled
, &r
))
3956 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
3958 /* If we have 10 or more types we might have more than a 1 digit
3959 index so we'll have to consume the whole count here. This
3960 will lose if the next thing is a type name preceded by a
3961 count but it's impossible to demangle that case properly
3962 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3963 Pc, ...)" or "(..., type12, char *, ...)" */
3964 if ((t
= consume_count(mangled
)) <= 0)
3971 if (!get_count (mangled
, &t
))
3976 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
3980 /* Validate the type index. Protect against illegal indices from
3981 malformed type strings. */
3982 if ((t
< 0) || (t
>= work
-> ntypes
))
3986 while (work
->nrepeats
> 0 || --r
>= 0)
3988 tem
= work
-> typevec
[t
];
3989 if (need_comma
&& PRINT_ARG_TYPES
)
3991 string_append (declp
, ", ");
3993 if (!do_arg (work
, &tem
, &arg
))
3997 if (PRINT_ARG_TYPES
)
3999 string_appends (declp
, &arg
);
4001 string_delete (&arg
);
4007 if (need_comma
&& PRINT_ARG_TYPES
)
4008 string_append (declp
, ", ");
4009 if (!do_arg (work
, mangled
, &arg
))
4011 if (PRINT_ARG_TYPES
)
4012 string_appends (declp
, &arg
);
4013 string_delete (&arg
);
4018 if (**mangled
== 'e')
4021 if (PRINT_ARG_TYPES
)
4025 string_append (declp
, ",");
4027 string_append (declp
, "...");
4031 if (PRINT_ARG_TYPES
)
4033 string_append (declp
, ")");
4038 /* Like demangle_args, but for demangling the argument lists of function
4039 and method pointers or references, not top-level declarations. */
4042 demangle_nested_args (work
, mangled
, declp
)
4043 struct work_stuff
*work
;
4044 const char **mangled
;
4047 string
* saved_previous_argument
;
4051 /* The G++ name-mangling algorithm does not remember types on nested
4052 argument lists, unless -fsquangling is used, and in that case the
4053 type vector updated by remember_type is not used. So, we turn
4054 off remembering of types here. */
4055 ++work
->forgetting_types
;
4057 /* For the repeat codes used with -fsquangling, we must keep track of
4058 the last argument. */
4059 saved_previous_argument
= work
->previous_argument
;
4060 saved_nrepeats
= work
->nrepeats
;
4061 work
->previous_argument
= 0;
4064 /* Actually demangle the arguments. */
4065 result
= demangle_args (work
, mangled
, declp
);
4067 /* Restore the previous_argument field. */
4068 if (work
->previous_argument
)
4069 string_delete (work
->previous_argument
);
4070 work
->previous_argument
= saved_previous_argument
;
4071 --work
->forgetting_types
;
4072 work
->nrepeats
= saved_nrepeats
;
4078 demangle_function_name (work
, mangled
, declp
, scan
)
4079 struct work_stuff
*work
;
4080 const char **mangled
;
4088 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4089 string_need (declp
, 1);
4090 *(declp
-> p
) = '\0';
4092 /* Consume the function name, including the "__" separating the name
4093 from the signature. We are guaranteed that SCAN points to the
4096 (*mangled
) = scan
+ 2;
4097 /* We may be looking at an instantiation of a template function:
4098 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4099 following _F marks the start of the function arguments. Handle
4100 the template arguments first. */
4102 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4104 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4105 /* This leaves MANGLED pointing to the 'F' marking func args */
4108 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4111 /* See if we have an ARM style constructor or destructor operator.
4112 If so, then just record it, clear the decl, and return.
4113 We can't build the actual constructor/destructor decl until later,
4114 when we recover the class name from the signature. */
4116 if (strcmp (declp
-> b
, "__ct") == 0)
4118 work
-> constructor
+= 1;
4119 string_clear (declp
);
4122 else if (strcmp (declp
-> b
, "__dt") == 0)
4124 work
-> destructor
+= 1;
4125 string_clear (declp
);
4130 if (declp
->p
- declp
->b
>= 3
4131 && declp
->b
[0] == 'o'
4132 && declp
->b
[1] == 'p'
4133 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4135 /* see if it's an assignment expression */
4136 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4137 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4139 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4141 int len
= declp
->p
- declp
->b
- 10;
4142 if ((int) strlen (optable
[i
].in
) == len
4143 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4145 string_clear (declp
);
4146 string_append (declp
, "operator");
4147 string_append (declp
, optable
[i
].out
);
4148 string_append (declp
, "=");
4155 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4157 int len
= declp
->p
- declp
->b
- 3;
4158 if ((int) strlen (optable
[i
].in
) == len
4159 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4161 string_clear (declp
);
4162 string_append (declp
, "operator");
4163 string_append (declp
, optable
[i
].out
);
4169 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4170 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4172 /* type conversion operator */
4174 if (do_type (work
, &tem
, &type
))
4176 string_clear (declp
);
4177 string_append (declp
, "operator ");
4178 string_appends (declp
, &type
);
4179 string_delete (&type
);
4182 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4183 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4186 /* type conversion operator. */
4188 if (do_type (work
, &tem
, &type
))
4190 string_clear (declp
);
4191 string_append (declp
, "operator ");
4192 string_appends (declp
, &type
);
4193 string_delete (&type
);
4196 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4197 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
4198 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
4200 if (declp
->b
[4] == '\0')
4203 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4205 if (strlen (optable
[i
].in
) == 2
4206 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4208 string_clear (declp
);
4209 string_append (declp
, "operator");
4210 string_append (declp
, optable
[i
].out
);
4217 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4220 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4222 if (strlen (optable
[i
].in
) == 3
4223 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4225 string_clear (declp
);
4226 string_append (declp
, "operator");
4227 string_append (declp
, optable
[i
].out
);
4236 /* a mini string-handling package */
4251 s
->p
= s
->b
= xmalloc (n
);
4254 else if (s
->e
- s
->p
< n
)
4259 s
->b
= xrealloc (s
->b
, n
);
4272 s
->b
= s
->e
= s
->p
= NULL
;
4280 s
->b
= s
->p
= s
->e
= NULL
;
4296 return (s
->b
== s
->p
);
4302 string_append (p
, s
)
4307 if (s
== NULL
|| *s
== '\0')
4311 memcpy (p
->p
, s
, n
);
4316 string_appends (p
, s
)
4325 memcpy (p
->p
, s
->b
, n
);
4331 string_appendn (p
, s
, n
)
4339 memcpy (p
->p
, s
, n
);
4345 string_prepend (p
, s
)
4349 if (s
!= NULL
&& *s
!= '\0')
4351 string_prependn (p
, s
, strlen (s
));
4356 string_prepends (p
, s
)
4361 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4366 string_prependn (p
, s
, n
)
4376 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4380 memcpy (p
->b
, s
, n
);
4386 string_append_template_idx (s
, idx
)
4390 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4391 sprintf(buf
, "T%d", idx
);
4392 string_append (s
, buf
);
4395 /* To generate a standalone demangler program for testing purposes,
4396 just compile and link this file with -DMAIN and libiberty.a. When
4397 run, it demangles each command line arg, or each stdin string, and
4398 prints the result on stdout. */
4404 static const char *program_name
;
4405 static const char *program_version
= VERSION
;
4406 static int flags
= DMGL_PARAMS
| DMGL_ANSI
;
4408 static void demangle_it
PARAMS ((char *));
4409 static void usage
PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN
;
4410 static void fatal
PARAMS ((const char *)) ATTRIBUTE_NORETURN
;
4413 demangle_it (mangled_name
)
4418 result
= cplus_demangle (mangled_name
, flags
);
4421 printf ("%s\n", mangled_name
);
4425 printf ("%s\n", result
);
4431 usage (stream
, status
)
4436 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4437 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4438 [--help] [--version] [arg...]\n",
4443 #define MBUF_SIZE 32767
4444 char mbuffer
[MBUF_SIZE
];
4446 /* Defined in the automatically-generated underscore.c. */
4447 extern int prepends_underscore
;
4449 int strip_underscore
= 0;
4451 static struct option long_options
[] = {
4452 {"strip-underscores", no_argument
, 0, '_'},
4453 {"format", required_argument
, 0, 's'},
4454 {"help", no_argument
, 0, 'h'},
4455 {"java", no_argument
, 0, 'j'},
4456 {"no-strip-underscores", no_argument
, 0, 'n'},
4457 {"version", no_argument
, 0, 'v'},
4458 {0, no_argument
, 0, 0}
4461 /* More 'friendly' abort that prints the line and file.
4462 config.h can #define abort fancy_abort if you like that sort of thing. */
4467 fatal ("Internal gcc abort.");
4471 /* Return the string of non-alnum characters that may occur
4472 as a valid symbol component, in the standard assembler symbol
4476 standard_symbol_characters ()
4482 /* Return the string of non-alnum characters that may occur
4483 as a valid symbol name component in an HP object file.
4485 Note that, since HP's compiler generates object code straight from
4486 C++ source, without going through an assembler, its mangled
4487 identifiers can use all sorts of characters that no assembler would
4488 tolerate, so the alphabet this function creates is a little odd.
4489 Here are some sample mangled identifiers offered by HP:
4491 typeid*__XT24AddressIndExpClassMember_
4492 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4493 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4495 This still seems really weird to me, since nowhere else in this
4496 file is there anything to recognize curly brackets, parens, etc.
4497 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4498 this is right, but I still strongly suspect that there's a
4499 misunderstanding here.
4501 If we decide it's better for c++filt to use HP's assembler syntax
4502 to scrape identifiers out of its input, here's the definition of
4503 the symbol name syntax from the HP assembler manual:
4505 Symbols are composed of uppercase and lowercase letters, decimal
4506 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4507 underscore (_). A symbol can begin with a letter, digit underscore or
4508 dollar sign. If a symbol begins with a digit, it must contain a
4509 non-digit character.
4513 hp_symbol_characters ()
4515 return "_$.<>#,*&[]:(){}";
4519 extern int main
PARAMS ((int, char **));
4528 const char *valid_symbols
;
4530 program_name
= argv
[0];
4532 strip_underscore
= prepends_underscore
;
4534 while ((c
= getopt_long (argc
, argv
, "_ns:j", long_options
, (int *) 0)) != EOF
)
4544 strip_underscore
= 0;
4547 printf ("GNU %s (C++ demangler), version %s\n", program_name
, program_version
);
4550 strip_underscore
= 1;
4556 if (strcmp (optarg
, "gnu") == 0)
4558 current_demangling_style
= gnu_demangling
;
4560 else if (strcmp (optarg
, "lucid") == 0)
4562 current_demangling_style
= lucid_demangling
;
4564 else if (strcmp (optarg
, "arm") == 0)
4566 current_demangling_style
= arm_demangling
;
4568 else if (strcmp (optarg
, "hp") == 0)
4570 current_demangling_style
= hp_demangling
;
4572 else if (strcmp (optarg
, "edg") == 0)
4574 current_demangling_style
= edg_demangling
;
4578 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
4579 program_name
, optarg
);
4588 for ( ; optind
< argc
; optind
++)
4590 demangle_it (argv
[optind
]);
4595 switch (current_demangling_style
)
4597 case gnu_demangling
:
4598 case lucid_demangling
:
4599 case arm_demangling
:
4600 case edg_demangling
:
4601 valid_symbols
= standard_symbol_characters ();
4604 valid_symbols
= hp_symbol_characters ();
4607 /* Folks should explicitly indicate the appropriate alphabet for
4608 each demangling. Providing a default would allow the
4609 question to go unconsidered. */
4617 /* Try to read a label. */
4618 while (c
!= EOF
&& (isalnum (c
) || strchr (valid_symbols
, c
)))
4620 if (i
>= MBUF_SIZE
-1)
4629 if (mbuffer
[0] == '.')
4631 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
4639 result
= cplus_demangle (mbuffer
+ skip_first
, flags
);
4642 if (mbuffer
[0] == '.')
4644 fputs (result
, stdout
);
4648 fputs (mbuffer
, stdout
);
4665 fprintf (stderr
, "%s: %s\n", program_name
, str
);
4673 register PTR value
= (PTR
) malloc (size
);
4675 fatal ("virtual memory exhausted");
4680 xrealloc (ptr
, size
)
4684 register PTR value
= (PTR
) realloc (ptr
, size
);
4686 fatal ("virtual memory exhausted");