1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 1998 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. */
255 #define SCOPE_STRING(work) "::"
257 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
258 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
260 /* Prototypes for local functions */
263 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
266 squangle_mop_up
PARAMS ((struct work_stuff
*));
270 demangle_method_args
PARAMS ((struct work_stuff
*, const char **, string
*));
274 internal_cplus_demangle
PARAMS ((struct work_stuff
*, const char *));
277 demangle_template_template_parm
PARAMS ((struct work_stuff
*work
,
278 const char **, string
*));
281 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*,
282 string
*, int, int));
285 arm_pt
PARAMS ((struct work_stuff
*, const char *, int, const char **,
289 demangle_arm_pt
PARAMS ((struct work_stuff
*, const char **, int, string
*));
292 demangle_class_name
PARAMS ((struct work_stuff
*, const char **, string
*));
295 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
299 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
302 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
305 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
308 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
311 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
314 arm_special
PARAMS ((const char **, string
*));
317 string_need
PARAMS ((string
*, int));
320 string_delete
PARAMS ((string
*));
323 string_init
PARAMS ((string
*));
326 string_clear
PARAMS ((string
*));
330 string_empty
PARAMS ((string
*));
334 string_append
PARAMS ((string
*, const char *));
337 string_appends
PARAMS ((string
*, string
*));
340 string_appendn
PARAMS ((string
*, const char *, int));
343 string_prepend
PARAMS ((string
*, const char *));
346 string_prependn
PARAMS ((string
*, const char *, int));
349 get_count
PARAMS ((const char **, int *));
352 consume_count
PARAMS ((const char **));
355 consume_count_with_underscores
PARAMS ((const char**));
358 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
361 demangle_nested_args
PARAMS ((struct work_stuff
*, const char**, string
*));
364 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
367 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
370 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
374 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
377 remember_Btype
PARAMS ((struct work_stuff
*, const char *, int, int));
380 register_Btype
PARAMS ((struct work_stuff
*));
383 remember_Ktype
PARAMS ((struct work_stuff
*, const char *, int));
386 forget_types
PARAMS ((struct work_stuff
*));
389 forget_B_and_K_types
PARAMS ((struct work_stuff
*));
392 string_prepends
PARAMS ((string
*, string
*));
395 demangle_template_value_parm
PARAMS ((struct work_stuff
*, const char**,
396 string
*, type_kind_t
));
399 do_hpacc_template_const_value
PARAMS ((struct work_stuff
*, const char **, string
*));
402 do_hpacc_template_literal
PARAMS ((struct work_stuff
*, const char **, string
*));
405 snarf_numeric_literal
PARAMS ((char **, string
*));
407 /* There is a TYPE_QUAL value for each type qualifier. They can be
408 combined by bitwise-or to form the complete set of qualifiers for a
411 #define TYPE_UNQUALIFIED 0x0
412 #define TYPE_QUAL_CONST 0x1
413 #define TYPE_QUAL_VOLATILE 0x2
414 #define TYPE_QUAL_RESTRICT 0x4
417 code_for_qualifier
PARAMS ((char));
420 qualifier_string
PARAMS ((int));
423 demangle_qualifier
PARAMS ((char));
425 /* Translate count to integer, consuming tokens in the process.
426 Conversion terminates on the first non-digit character.
427 Trying to consume something that isn't a count results in
428 no consumption of input and a return of 0. */
436 while (isdigit ((unsigned char)**type
))
439 count
+= **type
- '0';
446 /* Like consume_count, but for counts that are preceded and followed
447 by '_' if they are greater than 10. Also, -1 is returned for
448 failure, since 0 can be a valid value. */
451 consume_count_with_underscores (mangled
)
452 const char **mangled
;
456 if (**mangled
== '_')
459 if (!isdigit ((unsigned char)**mangled
))
462 idx
= consume_count (mangled
);
463 if (**mangled
!= '_')
464 /* The trailing underscore was missing. */
471 if (**mangled
< '0' || **mangled
> '9')
474 idx
= **mangled
- '0';
481 /* C is the code for a type-qualifier. Return the TYPE_QUAL
482 corresponding to this qualifier. */
485 code_for_qualifier (c
)
491 return TYPE_QUAL_CONST
;
494 return TYPE_QUAL_VOLATILE
;
497 return TYPE_QUAL_RESTRICT
;
503 /* C was an invalid qualifier. */
507 /* Return the string corresponding to the qualifiers given by
511 qualifier_string (type_quals
)
516 case TYPE_UNQUALIFIED
:
519 case TYPE_QUAL_CONST
:
522 case TYPE_QUAL_VOLATILE
:
525 case TYPE_QUAL_RESTRICT
:
528 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
529 return "const volatile";
531 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
532 return "const __restrict";
534 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
535 return "volatile __restrict";
537 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
538 return "const volatile __restrict";
544 /* TYPE_QUALS was an invalid qualifier set. */
548 /* C is the code for a type-qualifier. Return the string
549 corresponding to this qualifier. This function should only be
550 called with a valid qualifier code. */
553 demangle_qualifier (c
)
556 return qualifier_string (code_for_qualifier (c
));
560 cplus_demangle_opname (opname
, result
, options
)
567 struct work_stuff work
[1];
570 len
= strlen(opname
);
573 memset ((char *) work
, 0, sizeof (work
));
574 work
->options
= options
;
576 if (opname
[0] == '_' && opname
[1] == '_'
577 && opname
[2] == 'o' && opname
[3] == 'p')
580 /* type conversion operator. */
582 if (do_type (work
, &tem
, &type
))
584 strcat (result
, "operator ");
585 strncat (result
, type
.b
, type
.p
- type
.b
);
586 string_delete (&type
);
590 else if (opname
[0] == '_' && opname
[1] == '_'
591 && opname
[2] >= 'a' && opname
[2] <= 'z'
592 && opname
[3] >= 'a' && opname
[3] <= 'z')
594 if (opname
[4] == '\0')
598 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
600 if (strlen (optable
[i
].in
) == 2
601 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
603 strcat (result
, "operator");
604 strcat (result
, optable
[i
].out
);
612 if (opname
[2] == 'a' && opname
[5] == '\0')
616 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
618 if (strlen (optable
[i
].in
) == 3
619 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
621 strcat (result
, "operator");
622 strcat (result
, optable
[i
].out
);
633 && strchr (cplus_markers
, opname
[2]) != NULL
)
635 /* see if it's an assignment expression */
636 if (len
>= 10 /* op$assign_ */
637 && memcmp (opname
+ 3, "assign_", 7) == 0)
640 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
643 if ((int) strlen (optable
[i
].in
) == len1
644 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
646 strcat (result
, "operator");
647 strcat (result
, optable
[i
].out
);
648 strcat (result
, "=");
657 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
660 if ((int) strlen (optable
[i
].in
) == len1
661 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
663 strcat (result
, "operator");
664 strcat (result
, optable
[i
].out
);
671 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
672 && strchr (cplus_markers
, opname
[4]) != NULL
)
674 /* type conversion operator */
676 if (do_type (work
, &tem
, &type
))
678 strcat (result
, "operator ");
679 strncat (result
, type
.b
, type
.p
- type
.b
);
680 string_delete (&type
);
684 squangle_mop_up (work
);
688 /* Takes operator name as e.g. "++" and returns mangled
689 operator name (e.g. "postincrement_expr"), or NULL if not found.
691 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
692 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
695 cplus_mangle_opname (opname
, options
)
702 len
= strlen (opname
);
703 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
705 if ((int) strlen (optable
[i
].out
) == len
706 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
707 && memcmp (optable
[i
].out
, opname
, len
) == 0)
708 return optable
[i
].in
;
713 /* char *cplus_demangle (const char *mangled, int options)
715 If MANGLED is a mangled function name produced by GNU C++, then
716 a pointer to a malloced string giving a C++ representation
717 of the name will be returned; otherwise NULL will be returned.
718 It is the caller's responsibility to free the string which
721 The OPTIONS arg may contain one or more of the following bits:
723 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
725 DMGL_PARAMS Function parameters are included.
729 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
730 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
731 cplus_demangle ("foo__1Ai", 0) => "A::foo"
733 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
734 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
735 cplus_demangle ("foo__1Afe", 0) => "A::foo"
737 Note that any leading underscores, or other such characters prepended by
738 the compilation system, are presumed to have already been stripped from
742 cplus_demangle (mangled
, options
)
747 struct work_stuff work
[1];
748 memset ((char *) work
, 0, sizeof (work
));
749 work
-> options
= options
;
750 if ((work
-> options
& DMGL_STYLE_MASK
) == 0)
751 work
-> options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
753 ret
= internal_cplus_demangle (work
, mangled
);
754 squangle_mop_up (work
);
759 /* This function performs most of what cplus_demangle use to do, but
760 to be able to demangle a name with a B, K or n code, we need to
761 have a longer term memory of what types have been seen. The original
762 now intializes and cleans up the squangle code info, while internal
763 calls go directly to this routine to avoid resetting that info. */
766 internal_cplus_demangle (work
, mangled
)
767 struct work_stuff
*work
;
773 char *demangled
= NULL
;
775 s1
= work
->constructor
;
776 s2
= work
->destructor
;
777 s3
= work
->static_type
;
778 s4
= work
->type_quals
;
779 work
->constructor
= work
->destructor
= 0;
780 work
->type_quals
= TYPE_UNQUALIFIED
;
781 work
->dllimported
= 0;
783 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
787 /* First check to see if gnu style demangling is active and if the
788 string to be demangled contains a CPLUS_MARKER. If so, attempt to
789 recognize one of the gnu special forms rather than looking for a
790 standard prefix. In particular, don't worry about whether there
791 is a "__" string in the mangled string. Consider "_$_5__foo" for
794 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
796 success
= gnu_special (work
, &mangled
, &decl
);
800 success
= demangle_prefix (work
, &mangled
, &decl
);
802 if (success
&& (*mangled
!= '\0'))
804 success
= demangle_signature (work
, &mangled
, &decl
);
806 if (work
->constructor
== 2)
808 string_prepend (&decl
, "global constructors keyed to ");
809 work
->constructor
= 0;
811 else if (work
->destructor
== 2)
813 string_prepend (&decl
, "global destructors keyed to ");
814 work
->destructor
= 0;
816 else if (work
->dllimported
== 1)
818 string_prepend (&decl
, "import stub for ");
819 work
->dllimported
= 0;
821 demangled
= mop_up (work
, &decl
, success
);
823 work
->constructor
= s1
;
824 work
->destructor
= s2
;
825 work
->static_type
= s3
;
826 work
->type_quals
= s4
;
831 /* Clear out and squangling related storage */
833 squangle_mop_up (work
)
834 struct work_stuff
*work
;
836 /* clean up the B and K type mangling types. */
837 forget_B_and_K_types (work
);
838 if (work
-> btypevec
!= NULL
)
840 free ((char *) work
-> btypevec
);
842 if (work
-> ktypevec
!= NULL
)
844 free ((char *) work
-> ktypevec
);
848 /* Clear out any mangled storage */
851 mop_up (work
, declp
, success
)
852 struct work_stuff
*work
;
856 char *demangled
= NULL
;
858 /* Discard the remembered types, if any. */
861 if (work
-> typevec
!= NULL
)
863 free ((char *) work
-> typevec
);
864 work
-> typevec
= NULL
;
866 if (work
->tmpl_argvec
)
870 for (i
= 0; i
< work
->ntmpl_args
; i
++)
871 if (work
->tmpl_argvec
[i
])
872 free ((char*) work
->tmpl_argvec
[i
]);
874 free ((char*) work
->tmpl_argvec
);
875 work
->tmpl_argvec
= NULL
;
877 if (work
->previous_argument
)
879 string_delete (work
->previous_argument
);
880 free ((char*) work
->previous_argument
);
883 /* If demangling was successful, ensure that the demangled string is null
884 terminated and return it. Otherwise, free the demangling decl. */
888 string_delete (declp
);
892 string_appendn (declp
, "", 1);
893 demangled
= declp
-> b
;
902 demangle_signature -- demangle the signature part of a mangled name
907 demangle_signature (struct work_stuff *work, const char **mangled,
912 Consume and demangle the signature portion of the mangled name.
914 DECLP is the string where demangled output is being built. At
915 entry it contains the demangled root name from the mangled name
916 prefix. I.E. either a demangled operator name or the root function
917 name. In some special cases, it may contain nothing.
919 *MANGLED points to the current unconsumed location in the mangled
920 name. As tokens are consumed and demangling is performed, the
921 pointer is updated to continuously point at the next token to
924 Demangling GNU style mangled names is nasty because there is no
925 explicit token that marks the start of the outermost function
929 demangle_signature (work
, mangled
, declp
)
930 struct work_stuff
*work
;
931 const char **mangled
;
937 int expect_return_type
= 0;
938 const char *oldmangled
= NULL
;
942 while (success
&& (**mangled
!= '\0'))
947 oldmangled
= *mangled
;
948 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
950 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
951 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
957 oldmangled
= *mangled
;
958 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
959 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
967 /* Static member function */
968 if (oldmangled
== NULL
)
970 oldmangled
= *mangled
;
973 work
-> static_type
= 1;
979 work
->type_quals
|= code_for_qualifier (**mangled
);
981 /* a qualified member function */
982 if (oldmangled
== NULL
)
983 oldmangled
= *mangled
;
988 /* Local class name follows after "Lnnn_" */
991 while (**mangled
&& (**mangled
!= '_'))
1002 case '0': case '1': case '2': case '3': case '4':
1003 case '5': case '6': case '7': case '8': case '9':
1004 if (oldmangled
== NULL
)
1006 oldmangled
= *mangled
;
1008 work
->temp_start
= -1; /* uppermost call to demangle_class */
1009 success
= demangle_class (work
, mangled
, declp
);
1012 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1014 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1016 /* EDG and others will have the "F", so we let the loop cycle
1017 if we are looking at one. */
1018 if (**mangled
!= 'F')
1027 success
= do_type (work
, mangled
, &s
);
1030 string_append (&s
, SCOPE_STRING (work
));
1031 string_prepends (declp
, &s
);
1040 /* ARM/HP style demangling includes a specific 'F' character after
1041 the class name. For GNU style, it is just implied. So we can
1042 safely just consume any 'F' at this point and be compatible
1043 with either style. */
1049 /* For lucid/ARM/HP style we have to forget any types we might
1050 have remembered up to this point, since they were not argument
1051 types. GNU style considers all types seen as available for
1052 back references. See comment in demangle_args() */
1054 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1056 forget_types (work
);
1058 success
= demangle_args (work
, mangled
, declp
);
1059 /* After picking off the function args, we expect to either
1060 find the function return type (preceded by an '_') or the
1061 end of the string. */
1062 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1065 /* At this level, we do not care about the return type. */
1066 success
= do_type (work
, mangled
, &tname
);
1067 string_delete (&tname
);
1074 string_init(&trawname
);
1075 string_init(&tname
);
1076 if (oldmangled
== NULL
)
1078 oldmangled
= *mangled
;
1080 success
= demangle_template (work
, mangled
, &tname
,
1084 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1086 string_append (&tname
, SCOPE_STRING (work
));
1088 string_prepends(declp
, &tname
);
1089 if (work
-> destructor
& 1)
1091 string_prepend (&trawname
, "~");
1092 string_appends (declp
, &trawname
);
1093 work
->destructor
-= 1;
1095 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1097 string_appends (declp
, &trawname
);
1098 work
->constructor
-= 1;
1100 string_delete(&trawname
);
1101 string_delete(&tname
);
1107 if (GNU_DEMANGLING
&& expect_return_type
)
1109 /* Read the return type. */
1111 string_init (&return_type
);
1114 success
= do_type (work
, mangled
, &return_type
);
1115 APPEND_BLANK (&return_type
);
1117 string_prepends (declp
, &return_type
);
1118 string_delete (&return_type
);
1122 /* At the outermost level, we cannot have a return type specified,
1123 so if we run into another '_' at this point we are dealing with
1124 a mangled name that is either bogus, or has been mangled by
1125 some algorithm we don't know how to deal with. So just
1126 reject the entire demangling. */
1127 /* However, "_nnn" is an expected suffix for alternate entry point
1128 numbered nnn for a function, with HP aCC, so skip over that
1129 without reporting failure. pai/1997-09-04 */
1133 while (**mangled
&& isdigit (**mangled
))
1143 /* A G++ template function. Read the template arguments. */
1144 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1146 if (!(work
->constructor
& 1))
1147 expect_return_type
= 1;
1156 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1158 /* Assume we have stumbled onto the first outermost function
1159 argument token, and start processing args. */
1161 success
= demangle_args (work
, mangled
, declp
);
1165 /* Non-GNU demanglers use a specific token to mark the start
1166 of the outermost function argument tokens. Typically 'F',
1167 for ARM/HP-demangling, for example. So if we find something
1168 we are not prepared for, it must be an error. */
1174 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1177 if (success
&& expect_func
)
1180 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1182 forget_types (work
);
1184 success
= demangle_args (work
, mangled
, declp
);
1185 /* Since template include the mangling of their return types,
1186 we must set expect_func to 0 so that we don't try do
1187 demangle more arguments the next time we get here. */
1192 if (success
&& !func_done
)
1194 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1196 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1197 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1198 first case, and need to ensure that the '(void)' gets added to
1199 the current declp. Note that with ARM/HP, the first case
1200 represents the name of a static data member 'foo::bar',
1201 which is in the current declp, so we leave it alone. */
1202 success
= demangle_args (work
, mangled
, declp
);
1205 if (success
&& PRINT_ARG_TYPES
)
1207 if (work
->static_type
)
1208 string_append (declp
, " static");
1209 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1211 APPEND_BLANK (declp
);
1212 string_append (declp
, qualifier_string (work
->type_quals
));
1222 demangle_method_args (work
, mangled
, declp
)
1223 struct work_stuff
*work
;
1224 const char **mangled
;
1229 if (work
-> static_type
)
1231 string_append (declp
, *mangled
+ 1);
1232 *mangled
+= strlen (*mangled
);
1237 success
= demangle_args (work
, mangled
, declp
);
1245 demangle_template_template_parm (work
, mangled
, tname
)
1246 struct work_stuff
*work
;
1247 const char **mangled
;
1256 string_append (tname
, "template <");
1257 /* get size of template parameter list */
1258 if (get_count (mangled
, &r
))
1260 for (i
= 0; i
< r
; i
++)
1264 string_append (tname
, ", ");
1267 /* Z for type parameters */
1268 if (**mangled
== 'Z')
1271 string_append (tname
, "class");
1273 /* z for template parameters */
1274 else if (**mangled
== 'z')
1278 demangle_template_template_parm (work
, mangled
, tname
);
1286 /* temp is initialized in do_type */
1287 success
= do_type (work
, mangled
, &temp
);
1290 string_appends (tname
, &temp
);
1292 string_delete(&temp
);
1302 if (tname
->p
[-1] == '>')
1303 string_append (tname
, " ");
1304 string_append (tname
, "> class");
1309 demangle_integral_value (work
, mangled
, s
)
1310 struct work_stuff
*work
;
1311 const char** mangled
;
1316 if (**mangled
== 'E')
1318 int need_operator
= 0;
1321 string_appendn (s
, "(", 1);
1323 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1332 len
= strlen (*mangled
);
1335 i
< sizeof (optable
) / sizeof (optable
[0]);
1338 size_t l
= strlen (optable
[i
].in
);
1341 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1343 string_appendn (s
, " ", 1);
1344 string_append (s
, optable
[i
].out
);
1345 string_appendn (s
, " ", 1);
1358 success
= demangle_template_value_parm (work
, mangled
, s
,
1362 if (**mangled
!= 'W')
1366 string_appendn (s
, ")", 1);
1370 else if (**mangled
== 'Q' || **mangled
== 'K')
1371 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1376 if (**mangled
== 'm')
1378 string_appendn (s
, "-", 1);
1381 while (isdigit ((unsigned char)**mangled
))
1383 string_appendn (s
, *mangled
, 1);
1393 demangle_template_value_parm (work
, mangled
, s
, tk
)
1394 struct work_stuff
*work
;
1395 const char **mangled
;
1401 if (**mangled
== 'Y')
1403 /* The next argument is a template parameter. */
1407 idx
= consume_count_with_underscores (mangled
);
1409 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1410 || consume_count_with_underscores (mangled
) == -1)
1412 if (work
->tmpl_argvec
)
1413 string_append (s
, work
->tmpl_argvec
[idx
]);
1417 sprintf(buf
, "T%d", idx
);
1418 string_append (s
, buf
);
1421 else if (tk
== tk_integral
)
1422 success
= demangle_integral_value (work
, mangled
, s
);
1423 else if (tk
== tk_char
)
1427 if (**mangled
== 'm')
1429 string_appendn (s
, "-", 1);
1432 string_appendn (s
, "'", 1);
1433 val
= consume_count(mangled
);
1438 string_appendn (s
, &tmp
[0], 1);
1439 string_appendn (s
, "'", 1);
1441 else if (tk
== tk_bool
)
1443 int val
= consume_count (mangled
);
1445 string_appendn (s
, "false", 5);
1447 string_appendn (s
, "true", 4);
1451 else if (tk
== tk_real
)
1453 if (**mangled
== 'm')
1455 string_appendn (s
, "-", 1);
1458 while (isdigit ((unsigned char)**mangled
))
1460 string_appendn (s
, *mangled
, 1);
1463 if (**mangled
== '.') /* fraction */
1465 string_appendn (s
, ".", 1);
1467 while (isdigit ((unsigned char)**mangled
))
1469 string_appendn (s
, *mangled
, 1);
1473 if (**mangled
== 'e') /* exponent */
1475 string_appendn (s
, "e", 1);
1477 while (isdigit ((unsigned char)**mangled
))
1479 string_appendn (s
, *mangled
, 1);
1484 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1486 int symbol_len
= consume_count (mangled
);
1487 if (symbol_len
== 0)
1489 if (symbol_len
== 0)
1490 string_appendn (s
, "0", 1);
1493 char *p
= xmalloc (symbol_len
+ 1), *q
;
1494 strncpy (p
, *mangled
, symbol_len
);
1495 p
[symbol_len
] = '\0';
1496 /* We use cplus_demangle here, rather than
1497 internal_cplus_demangle, because the name of the entity
1498 mangled here does not make use of any of the squangling
1499 or type-code information we have built up thus far; it is
1500 mangled independently. */
1501 q
= cplus_demangle (p
, work
->options
);
1502 if (tk
== tk_pointer
)
1503 string_appendn (s
, "&", 1);
1504 /* FIXME: Pointer-to-member constants should get a
1505 qualifying class name here. */
1508 string_append (s
, q
);
1512 string_append (s
, p
);
1515 *mangled
+= symbol_len
;
1521 /* Demangle the template name in MANGLED. The full name of the
1522 template (e.g., S<int>) is placed in TNAME. The name without the
1523 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1524 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1525 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1526 the tmeplate is remembered in the list of back-referenceable
1530 demangle_template (work
, mangled
, tname
, trawname
, is_type
, remember
)
1531 struct work_stuff
*work
;
1532 const char **mangled
;
1550 bindex
= register_Btype (work
);
1552 /* get template name */
1553 if (**mangled
== 'z')
1559 idx
= consume_count_with_underscores (mangled
);
1561 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1562 || consume_count_with_underscores (mangled
) == -1)
1565 if (work
->tmpl_argvec
)
1567 string_append (tname
, work
->tmpl_argvec
[idx
]);
1569 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1574 sprintf(buf
, "T%d", idx
);
1575 string_append (tname
, buf
);
1577 string_append (trawname
, buf
);
1582 if ((r
= consume_count (mangled
)) == 0
1583 || (int) strlen (*mangled
) < r
)
1587 string_appendn (tname
, *mangled
, r
);
1589 string_appendn (trawname
, *mangled
, r
);
1593 string_append (tname
, "<");
1594 /* get size of template parameter list */
1595 if (!get_count (mangled
, &r
))
1601 /* Create an array for saving the template argument values. */
1602 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
1603 work
->ntmpl_args
= r
;
1604 for (i
= 0; i
< r
; i
++)
1605 work
->tmpl_argvec
[i
] = 0;
1607 for (i
= 0; i
< r
; i
++)
1611 string_append (tname
, ", ");
1613 /* Z for type parameters */
1614 if (**mangled
== 'Z')
1617 /* temp is initialized in do_type */
1618 success
= do_type (work
, mangled
, &temp
);
1621 string_appends (tname
, &temp
);
1625 /* Save the template argument. */
1626 int len
= temp
.p
- temp
.b
;
1627 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1628 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
1629 work
->tmpl_argvec
[i
][len
] = '\0';
1632 string_delete(&temp
);
1638 /* z for template parameters */
1639 else if (**mangled
== 'z')
1643 success
= demangle_template_template_parm (work
, mangled
, tname
);
1646 && (r2
= consume_count (mangled
)) > 0
1647 && (int) strlen (*mangled
) >= r2
)
1649 string_append (tname
, " ");
1650 string_appendn (tname
, *mangled
, r2
);
1653 /* Save the template argument. */
1655 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1656 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
1657 work
->tmpl_argvec
[i
][len
] = '\0';
1671 /* otherwise, value parameter */
1673 /* temp is initialized in do_type */
1674 success
= do_type (work
, mangled
, &temp
);
1675 string_delete(&temp
);
1687 success
= demangle_template_value_parm (work
, mangled
, s
,
1688 (type_kind_t
) success
);
1700 int len
= s
->p
- s
->b
;
1701 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1702 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
1703 work
->tmpl_argvec
[i
][len
] = '\0';
1705 string_appends (tname
, s
);
1712 if (tname
->p
[-1] == '>')
1713 string_append (tname
, " ");
1714 string_append (tname
, ">");
1717 if (is_type
&& remember
)
1718 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
1721 if (work -> static_type)
1723 string_append (declp, *mangled + 1);
1724 *mangled += strlen (*mangled);
1729 success = demangle_args (work, mangled, declp);
1737 arm_pt (work
, mangled
, n
, anchor
, args
)
1738 struct work_stuff
*work
;
1739 const char *mangled
;
1741 const char **anchor
, **args
;
1743 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1744 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1745 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= mystrstr (mangled
, "__pt__")))
1748 *args
= *anchor
+ 6;
1749 len
= consume_count (args
);
1750 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1756 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
1758 if ((*anchor
= mystrstr (mangled
, "__tm__"))
1759 || (*anchor
= mystrstr (mangled
, "__ps__"))
1760 || (*anchor
= mystrstr (mangled
, "__pt__")))
1763 *args
= *anchor
+ 6;
1764 len
= consume_count (args
);
1765 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1771 else if (*anchor
= mystrstr (mangled
, "__S"))
1774 *args
= *anchor
+ 3;
1775 len
= consume_count (args
);
1776 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1788 demangle_arm_hp_template (work
, mangled
, n
, declp
)
1789 struct work_stuff
*work
;
1790 const char **mangled
;
1796 const char *e
= *mangled
+ n
;
1799 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1801 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
1803 char *start_spec_args
= NULL
;
1805 /* First check for and omit template specialization pseudo-arguments,
1806 such as in "Spec<#1,#1.*>" */
1807 start_spec_args
= strchr (*mangled
, '<');
1808 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
1809 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
1811 string_appendn (declp
, *mangled
, n
);
1812 (*mangled
) += n
+ 1;
1814 if (work
->temp_start
== -1) /* non-recursive call */
1815 work
->temp_start
= declp
->p
- declp
->b
;
1816 string_append (declp
, "<");
1819 string_clear (&arg
);
1823 /* 'T' signals a type parameter */
1825 if (!do_type (work
, mangled
, &arg
))
1826 goto hpacc_template_args_done
;
1831 /* 'U' or 'S' signals an integral value */
1832 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
1833 goto hpacc_template_args_done
;
1837 /* 'A' signals a named constant expression (literal) */
1838 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
1839 goto hpacc_template_args_done
;
1843 /* Today, 1997-09-03, we have only the above types
1844 of template parameters */
1845 /* FIXME: maybe this should fail and return null */
1846 goto hpacc_template_args_done
;
1848 string_appends (declp
, &arg
);
1849 /* Check if we're at the end of template args.
1850 0 if at end of static member of template class,
1851 _ if done with template args for a function */
1852 if ((**mangled
== '\000') || (**mangled
== '_'))
1855 string_append (declp
, ",");
1857 hpacc_template_args_done
:
1858 string_append (declp
, ">");
1859 string_delete (&arg
);
1860 if (**mangled
== '_')
1864 /* ARM template? (Also handles HP cfront extensions) */
1865 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
1870 string_appendn (declp
, *mangled
, p
- *mangled
);
1871 if (work
->temp_start
== -1) /* non-recursive call */
1872 work
->temp_start
= declp
->p
- declp
->b
;
1873 string_append (declp
, "<");
1874 /* should do error checking here */
1876 string_clear (&arg
);
1878 /* Check for type or literal here */
1881 /* HP cfront extensions to ARM for template args */
1882 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1883 /* FIXME: We handle only numeric literals for HP cfront */
1885 /* A typed constant value follows */
1887 if (!do_type (work
, &args
, &type_str
))
1888 goto cfront_template_args_done
;
1889 string_append (&arg
, "(");
1890 string_appends (&arg
, &type_str
);
1891 string_append (&arg
, ")");
1893 goto cfront_template_args_done
;
1895 /* Now snarf a literal value following 'L' */
1896 if (!snarf_numeric_literal (&args
, &arg
))
1897 goto cfront_template_args_done
;
1901 /* Snarf a literal following 'L' */
1903 if (!snarf_numeric_literal (&args
, &arg
))
1904 goto cfront_template_args_done
;
1907 /* Not handling other HP cfront stuff */
1908 if (!do_type (work
, &args
, &arg
))
1909 goto cfront_template_args_done
;
1911 string_appends (declp
, &arg
);
1912 string_append (declp
, ",");
1914 cfront_template_args_done
:
1915 string_delete (&arg
);
1917 --declp
->p
; /* remove extra comma */
1918 string_append (declp
, ">");
1920 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
1921 && (*mangled
)[9] == 'N'
1922 && (*mangled
)[8] == (*mangled
)[10]
1923 && strchr (cplus_markers
, (*mangled
)[8]))
1925 /* A member of the anonymous namespace. */
1926 string_append (declp
, "{anonymous}");
1930 if (work
->temp_start
== -1) /* non-recursive call only */
1931 work
->temp_start
= 0; /* disable in recursive calls */
1932 string_appendn (declp
, *mangled
, n
);
1937 /* Extract a class name, possibly a template with arguments, from the
1938 mangled string; qualifiers, local class indicators, etc. have
1939 already been dealt with */
1942 demangle_class_name (work
, mangled
, declp
)
1943 struct work_stuff
*work
;
1944 const char **mangled
;
1950 n
= consume_count (mangled
);
1951 if ((int) strlen (*mangled
) >= n
)
1953 demangle_arm_hp_template (work
, mangled
, n
, declp
);
1964 demangle_class -- demangle a mangled class sequence
1969 demangle_class (struct work_stuff *work, const char **mangled,
1974 DECLP points to the buffer into which demangling is being done.
1976 *MANGLED points to the current token to be demangled. On input,
1977 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1978 On exit, it points to the next token after the mangled class on
1979 success, or the first unconsumed token on failure.
1981 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1982 we are demangling a constructor or destructor. In this case
1983 we prepend "class::class" or "class::~class" to DECLP.
1985 Otherwise, we prepend "class::" to the current DECLP.
1987 Reset the constructor/destructor flags once they have been
1988 "consumed". This allows demangle_class to be called later during
1989 the same demangling, to do normal class demangling.
1991 Returns 1 if demangling is successful, 0 otherwise.
1996 demangle_class (work
, mangled
, declp
)
1997 struct work_stuff
*work
;
1998 const char **mangled
;
2004 char *save_class_name_end
= 0;
2006 string_init (&class_name
);
2007 btype
= register_Btype (work
);
2008 if (demangle_class_name (work
, mangled
, &class_name
))
2010 save_class_name_end
= class_name
.p
;
2011 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2013 /* adjust so we don't include template args */
2014 if (work
->temp_start
&& (work
->temp_start
!= -1))
2016 class_name
.p
= class_name
.b
+ work
->temp_start
;
2018 string_prepends (declp
, &class_name
);
2019 if (work
-> destructor
& 1)
2021 string_prepend (declp
, "~");
2022 work
-> destructor
-= 1;
2026 work
-> constructor
-= 1;
2029 class_name
.p
= save_class_name_end
;
2030 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2031 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2032 string_prepend (declp
, SCOPE_STRING (work
));
2033 string_prepends (declp
, &class_name
);
2036 string_delete (&class_name
);
2044 demangle_prefix -- consume the mangled name prefix and find signature
2049 demangle_prefix (struct work_stuff *work, const char **mangled,
2054 Consume and demangle the prefix of the mangled name.
2056 DECLP points to the string buffer into which demangled output is
2057 placed. On entry, the buffer is empty. On exit it contains
2058 the root function name, the demangled operator name, or in some
2059 special cases either nothing or the completely demangled result.
2061 MANGLED points to the current pointer into the mangled name. As each
2062 token of the mangled name is consumed, it is updated. Upon entry
2063 the current mangled name pointer points to the first character of
2064 the mangled name. Upon exit, it should point to the first character
2065 of the signature if demangling was successful, or to the first
2066 unconsumed character if demangling of the prefix was unsuccessful.
2068 Returns 1 on success, 0 otherwise.
2072 demangle_prefix (work
, mangled
, declp
)
2073 struct work_stuff
*work
;
2074 const char **mangled
;
2081 if (strlen(*mangled
) > 6
2082 && (strncmp(*mangled
, "_imp__", 6) == 0
2083 || strncmp(*mangled
, "__imp_", 6) == 0))
2085 /* it's a symbol imported from a PE dynamic library. Check for both
2086 new style prefix _imp__ and legacy __imp_ used by older versions
2089 work
->dllimported
= 1;
2091 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2093 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2094 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2096 if ((*mangled
)[9] == 'D')
2098 /* it's a GNU global destructor to be executed at program exit */
2100 work
->destructor
= 2;
2101 if (gnu_special (work
, mangled
, declp
))
2104 else if ((*mangled
)[9] == 'I')
2106 /* it's a GNU global constructor to be executed at program init */
2108 work
->constructor
= 2;
2109 if (gnu_special (work
, mangled
, declp
))
2114 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2116 /* it's a ARM global destructor to be executed at program exit */
2118 work
->destructor
= 2;
2120 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2122 /* it's a ARM global constructor to be executed at program initial */
2124 work
->constructor
= 2;
2127 /* This block of code is a reduction in strength time optimization
2129 scan = mystrstr (*mangled, "__"); */
2135 scan
= strchr (scan
, '_');
2136 } while (scan
!= NULL
&& *++scan
!= '_');
2138 if (scan
!= NULL
) --scan
;
2143 /* We found a sequence of two or more '_', ensure that we start at
2144 the last pair in the sequence. */
2145 i
= strspn (scan
, "_");
2156 else if (work
-> static_type
)
2158 if (!isdigit ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2163 else if ((scan
== *mangled
)
2164 && (isdigit ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2165 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2167 /* The ARM says nothing about the mangling of local variables.
2168 But cfront mangles local variables by prepending __<nesting_level>
2169 to them. As an extension to ARM demangling we handle this case. */
2170 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2171 && isdigit ((unsigned char)scan
[2]))
2173 *mangled
= scan
+ 2;
2174 consume_count (mangled
);
2175 string_append (declp
, *mangled
);
2176 *mangled
+= strlen (*mangled
);
2181 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2182 names like __Q2_3foo3bar for nested type names. So don't accept
2183 this style of constructor for cfront demangling. A GNU
2184 style member-template constructor starts with 'H'. */
2185 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2186 work
-> constructor
+= 1;
2187 *mangled
= scan
+ 2;
2190 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2192 /* Cfront-style parameterized type. Handled later as a signature. */
2196 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2198 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2199 || (scan
[2] == 'p' && scan
[3] == 's')
2200 || (scan
[2] == 'p' && scan
[3] == 't')))
2202 /* EDG-style parameterized type. Handled later as a signature. */
2206 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2208 else if ((scan
== *mangled
) && !isdigit ((unsigned char)scan
[2])
2209 && (scan
[2] != 't'))
2211 /* Mangled name starts with "__". Skip over any leading '_' characters,
2212 then find the next "__" that separates the prefix from the signature.
2214 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2215 || (arm_special (mangled
, declp
) == 0))
2217 while (*scan
== '_')
2221 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2223 /* No separator (I.E. "__not_mangled"), or empty signature
2224 (I.E. "__not_mangled_either__") */
2230 /* Look for the LAST occurrence of __, allowing names to have
2231 the '__' sequence embedded in them.*/
2232 while ((tmp
= mystrstr (scan
+2, "__")) != NULL
)
2234 if (*(scan
+ 2) == '\0')
2237 demangle_function_name (work
, mangled
, declp
, scan
);
2241 else if (*(scan
+ 2) != '\0')
2243 /* Mangled name does not start with "__" but does have one somewhere
2244 in there with non empty stuff after it. Looks like a global
2246 demangle_function_name (work
, mangled
, declp
, scan
);
2250 /* Doesn't look like a mangled name */
2254 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2256 string_append (declp
, *mangled
);
2257 *mangled
+= strlen (*mangled
);
2267 gnu_special -- special handling of gnu mangled strings
2272 gnu_special (struct work_stuff *work, const char **mangled,
2278 Process some special GNU style mangling forms that don't fit
2279 the normal pattern. For example:
2281 _$_3foo (destructor for class foo)
2282 _vt$foo (foo virtual table)
2283 _vt$foo$bar (foo::bar virtual table)
2284 __vt_foo (foo virtual table, new style with thunks)
2285 _3foo$varname (static data member)
2286 _Q22rs2tu$vw (static data member)
2287 __t6vector1Zii (constructor with template)
2288 __thunk_4__$_7ostream (virtual function thunk)
2292 gnu_special (work
, mangled
, declp
)
2293 struct work_stuff
*work
;
2294 const char **mangled
;
2301 if ((*mangled
)[0] == '_'
2302 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2303 && (*mangled
)[2] == '_')
2305 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2307 work
-> destructor
+= 1;
2309 else if ((*mangled
)[0] == '_'
2310 && (((*mangled
)[1] == '_'
2311 && (*mangled
)[2] == 'v'
2312 && (*mangled
)[3] == 't'
2313 && (*mangled
)[4] == '_')
2314 || ((*mangled
)[1] == 'v'
2315 && (*mangled
)[2] == 't'
2316 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2318 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2319 and create the decl. Note that we consume the entire mangled
2320 input string, which means that demangle_signature has no work
2322 if ((*mangled
)[2] == 'v')
2323 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2325 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2326 while (**mangled
!= '\0')
2332 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2335 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2339 if (isdigit((unsigned char)*mangled
[0]))
2341 n
= consume_count(mangled
);
2342 /* We may be seeing a too-large size, or else a
2343 ".<digits>" indicating a static local symbol. In
2344 any case, declare victory and move on; *don't* try
2345 to use n to allocate. */
2346 if (n
> (int) strlen (*mangled
))
2354 n
= strcspn (*mangled
, cplus_markers
);
2356 string_appendn (declp
, *mangled
, n
);
2360 p
= strpbrk (*mangled
, cplus_markers
);
2361 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2365 string_append (declp
, SCOPE_STRING (work
));
2376 string_append (declp
, " virtual table");
2378 else if ((*mangled
)[0] == '_'
2379 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2380 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2382 /* static data member, "_3foo$varname" for example */
2388 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2391 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2394 n
= consume_count (mangled
);
2395 string_appendn (declp
, *mangled
, n
);
2398 if (success
&& (p
== *mangled
))
2400 /* Consumed everything up to the cplus_marker, append the
2403 string_append (declp
, SCOPE_STRING (work
));
2404 n
= strlen (*mangled
);
2405 string_appendn (declp
, *mangled
, n
);
2413 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2415 int delta
= ((*mangled
) += 8, consume_count (mangled
));
2416 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2420 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2421 string_append (declp
, buf
);
2422 string_append (declp
, method
);
2424 n
= strlen (*mangled
);
2432 else if (strncmp (*mangled
, "__t", 3) == 0
2433 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2435 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2441 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2444 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2447 success
= demangle_fund_type (work
, mangled
, declp
);
2450 if (success
&& **mangled
!= '\0')
2453 string_append (declp
, p
);
2463 recursively_demangle(work
, mangled
, result
, namelength
)
2464 struct work_stuff
*work
;
2465 const char **mangled
;
2469 char * recurse
= (char *)NULL
;
2470 char * recurse_dem
= (char *)NULL
;
2472 recurse
= (char *) xmalloc (namelength
+ 1);
2473 memcpy (recurse
, *mangled
, namelength
);
2474 recurse
[namelength
] = '\000';
2476 recurse_dem
= cplus_demangle (recurse
, work
->options
);
2480 string_append (result
, recurse_dem
);
2485 string_appendn (result
, *mangled
, namelength
);
2488 *mangled
+= namelength
;
2495 arm_special -- special handling of ARM/lucid mangled strings
2500 arm_special (const char **mangled,
2506 Process some special ARM style mangling forms that don't fit
2507 the normal pattern. For example:
2509 __vtbl__3foo (foo virtual table)
2510 __vtbl__3foo__3bar (bar::foo virtual table)
2515 arm_special (mangled
, declp
)
2516 const char **mangled
;
2523 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
2525 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2526 and create the decl. Note that we consume the entire mangled
2527 input string, which means that demangle_signature has no work
2529 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
2530 while (*scan
!= '\0') /* first check it can be demangled */
2532 n
= consume_count (&scan
);
2535 return (0); /* no good */
2538 if (scan
[0] == '_' && scan
[1] == '_')
2543 (*mangled
) += ARM_VTABLE_STRLEN
;
2544 while (**mangled
!= '\0')
2546 n
= consume_count (mangled
);
2547 string_prependn (declp
, *mangled
, n
);
2549 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
2551 string_prepend (declp
, "::");
2555 string_append (declp
, " virtual table");
2568 demangle_qualified -- demangle 'Q' qualified name strings
2573 demangle_qualified (struct work_stuff *, const char *mangled,
2574 string *result, int isfuncname, int append);
2578 Demangle a qualified name, such as "Q25Outer5Inner" which is
2579 the mangled form of "Outer::Inner". The demangled output is
2580 prepended or appended to the result string according to the
2581 state of the append flag.
2583 If isfuncname is nonzero, then the qualified name we are building
2584 is going to be used as a member function name, so if it is a
2585 constructor or destructor function, append an appropriate
2586 constructor or destructor name. I.E. for the above example,
2587 the result for use as a constructor is "Outer::Inner::Inner"
2588 and the result for use as a destructor is "Outer::Inner::~Inner".
2592 Numeric conversion is ASCII dependent (FIXME).
2597 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
2598 struct work_stuff
*work
;
2599 const char **mangled
;
2610 int bindex
= register_Btype (work
);
2612 /* We only make use of ISFUNCNAME if the entity is a constructor or
2614 isfuncname
= (isfuncname
2615 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
2617 string_init (&temp
);
2618 string_init (&last_name
);
2620 if ((*mangled
)[0] == 'K')
2622 /* Squangling qualified name reuse */
2625 idx
= consume_count_with_underscores (mangled
);
2626 if (idx
== -1 || idx
>= work
-> numk
)
2629 string_append (&temp
, work
-> ktypevec
[idx
]);
2632 switch ((*mangled
)[1])
2635 /* GNU mangled name with more than 9 classes. The count is preceded
2636 by an underscore (to distinguish it from the <= 9 case) and followed
2637 by an underscore. */
2639 qualifiers
= atoi (p
);
2640 if (!isdigit ((unsigned char)*p
) || *p
== '0')
2643 /* Skip the digits. */
2644 while (isdigit ((unsigned char)*p
))
2662 /* The count is in a single digit. */
2663 num
[0] = (*mangled
)[1];
2665 qualifiers
= atoi (num
);
2667 /* If there is an underscore after the digit, skip it. This is
2668 said to be for ARM-qualified names, but the ARM makes no
2669 mention of such an underscore. Perhaps cfront uses one. */
2670 if ((*mangled
)[2] == '_')
2685 /* Pick off the names and collect them in the temp buffer in the order
2686 in which they are found, separated by '::'. */
2688 while (qualifiers
-- > 0)
2691 string_clear (&last_name
);
2693 if (*mangled
[0] == '_')
2696 if (*mangled
[0] == 't')
2698 /* Here we always append to TEMP since we will want to use
2699 the template name without the template parameters as a
2700 constructor or destructor name. The appropriate
2701 (parameter-less) value is returned by demangle_template
2702 in LAST_NAME. We do not remember the template type here,
2703 in order to match the G++ mangling algorithm. */
2704 success
= demangle_template(work
, mangled
, &temp
,
2709 else if (*mangled
[0] == 'K')
2713 idx
= consume_count_with_underscores (mangled
);
2714 if (idx
== -1 || idx
>= work
->numk
)
2717 string_append (&temp
, work
->ktypevec
[idx
]);
2720 if (!success
) break;
2727 /* Now recursively demangle the qualifier
2728 * This is necessary to deal with templates in
2729 * mangling styles like EDG */
2730 namelength
= consume_count (mangled
);
2731 recursively_demangle(work
, mangled
, &temp
, namelength
);
2735 success
= do_type (work
, mangled
, &last_name
);
2738 string_appends (&temp
, &last_name
);
2743 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
2746 string_append (&temp
, SCOPE_STRING (work
));
2749 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
2751 /* If we are using the result as a function name, we need to append
2752 the appropriate '::' separated constructor or destructor name.
2753 We do this here because this is the most convenient place, where
2754 we already have a pointer to the name and the length of the name. */
2758 string_append (&temp
, SCOPE_STRING (work
));
2759 if (work
-> destructor
& 1)
2760 string_append (&temp
, "~");
2761 string_appends (&temp
, &last_name
);
2764 /* Now either prepend the temp buffer to the result, or append it,
2765 depending upon the state of the append flag. */
2768 string_appends (result
, &temp
);
2771 if (!STRING_EMPTY (result
))
2772 string_append (&temp
, SCOPE_STRING (work
));
2773 string_prepends (result
, &temp
);
2776 string_delete (&last_name
);
2777 string_delete (&temp
);
2785 get_count -- convert an ascii count to integer, consuming tokens
2790 get_count (const char **type, int *count)
2794 Return 0 if no conversion is performed, 1 if a string is converted.
2798 get_count (type
, count
)
2805 if (!isdigit ((unsigned char)**type
))
2811 *count
= **type
- '0';
2813 if (isdigit ((unsigned char)**type
))
2823 while (isdigit ((unsigned char)*p
));
2834 /* RESULT will be initialised here; it will be freed on failure. The
2835 value returned is really a type_kind_t. */
2838 do_type (work
, mangled
, result
)
2839 struct work_stuff
*work
;
2840 const char **mangled
;
2847 const char *remembered_type
;
2850 type_kind_t tk
= tk_none
;
2852 string_init (&btype
);
2853 string_init (&decl
);
2854 string_init (result
);
2858 while (success
&& !done
)
2864 /* A pointer type */
2868 string_prepend (&decl
, "*");
2873 /* A reference type */
2876 string_prepend (&decl
, "&");
2885 if (!STRING_EMPTY (&decl
)
2886 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
2888 string_prepend (&decl
, "(");
2889 string_append (&decl
, ")");
2891 string_append (&decl
, "[");
2892 if (**mangled
!= '_')
2893 success
= demangle_template_value_parm (work
, mangled
, &decl
,
2895 if (**mangled
== '_')
2897 string_append (&decl
, "]");
2901 /* A back reference to a previously seen type */
2904 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
2910 remembered_type
= work
-> typevec
[n
];
2911 mangled
= &remembered_type
;
2918 if (!STRING_EMPTY (&decl
)
2919 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
2921 string_prepend (&decl
, "(");
2922 string_append (&decl
, ")");
2924 /* After picking off the function args, we expect to either find the
2925 function return type (preceded by an '_') or the end of the
2927 if (!demangle_nested_args (work
, mangled
, &decl
)
2928 || (**mangled
!= '_' && **mangled
!= '\0'))
2933 if (success
&& (**mangled
== '_'))
2940 type_quals
= TYPE_UNQUALIFIED
;
2942 member
= **mangled
== 'M';
2944 if (!isdigit ((unsigned char)**mangled
) && **mangled
!= 't')
2950 string_append (&decl
, ")");
2951 string_prepend (&decl
, SCOPE_STRING (work
));
2952 if (isdigit ((unsigned char)**mangled
))
2954 n
= consume_count (mangled
);
2955 if ((int) strlen (*mangled
) < n
)
2960 string_prependn (&decl
, *mangled
, n
);
2966 string_init (&temp
);
2967 success
= demangle_template (work
, mangled
, &temp
,
2971 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
2972 string_clear (&temp
);
2977 string_prepend (&decl
, "(");
2985 type_quals
|= code_for_qualifier (**mangled
);
2993 if (*(*mangled
)++ != 'F')
2999 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3000 || **mangled
!= '_')
3006 if (! PRINT_ANSI_QUALIFIERS
)
3010 if (type_quals
!= TYPE_UNQUALIFIED
)
3012 APPEND_BLANK (&decl
);
3013 string_append (&decl
, qualifier_string (type_quals
));
3024 if (PRINT_ANSI_QUALIFIERS
)
3026 if (!STRING_EMPTY (&decl
))
3027 string_prepend (&decl
, " ");
3029 string_prepend (&decl
, demangle_qualifier (**mangled
));
3044 if (success
) switch (**mangled
)
3046 /* A qualified name, such as "Outer::Inner". */
3050 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3054 /* A back reference to a previously seen squangled type */
3057 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3060 string_append (result
, work
->btypevec
[n
]);
3065 /* A template parm. We substitute the corresponding argument. */
3070 idx
= consume_count_with_underscores (mangled
);
3073 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3074 || consume_count_with_underscores (mangled
) == -1)
3080 if (work
->tmpl_argvec
)
3081 string_append (result
, work
->tmpl_argvec
[idx
]);
3085 sprintf(buf
, "T%d", idx
);
3086 string_append (result
, buf
);
3094 success
= demangle_fund_type (work
, mangled
, result
);
3096 tk
= (type_kind_t
) success
;
3102 if (!STRING_EMPTY (&decl
))
3104 string_append (result
, " ");
3105 string_appends (result
, &decl
);
3109 string_delete (result
);
3110 string_delete (&decl
);
3113 /* Assume an integral type, if we're not sure. */
3114 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3119 /* Given a pointer to a type string that represents a fundamental type
3120 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3121 string in which the demangled output is being built in RESULT, and
3122 the WORK structure, decode the types and add them to the result.
3127 "Sl" => "signed long"
3128 "CUs" => "const unsigned short"
3130 The value returned is really a type_kind_t. */
3133 demangle_fund_type (work
, mangled
, result
)
3134 struct work_stuff
*work
;
3135 const char **mangled
;
3143 type_kind_t tk
= tk_integral
;
3145 string_init (&btype
);
3147 /* First pick off any type qualifiers. There can be more than one. */
3157 if (PRINT_ANSI_QUALIFIERS
)
3159 APPEND_BLANK (result
);
3160 string_append (result
, demangle_qualifier (**mangled
));
3165 APPEND_BLANK (result
);
3166 string_append (result
, "unsigned");
3168 case 'S': /* signed char only */
3170 APPEND_BLANK (result
);
3171 string_append (result
, "signed");
3175 APPEND_BLANK (result
);
3176 string_append (result
, "__complex");
3184 /* Now pick off the fundamental type. There can be only one. */
3193 APPEND_BLANK (result
);
3194 string_append (result
, "void");
3198 APPEND_BLANK (result
);
3199 string_append (result
, "long long");
3203 APPEND_BLANK (result
);
3204 string_append (result
, "long");
3208 APPEND_BLANK (result
);
3209 string_append (result
, "int");
3213 APPEND_BLANK (result
);
3214 string_append (result
, "short");
3218 APPEND_BLANK (result
);
3219 string_append (result
, "bool");
3224 APPEND_BLANK (result
);
3225 string_append (result
, "char");
3230 APPEND_BLANK (result
);
3231 string_append (result
, "wchar_t");
3236 APPEND_BLANK (result
);
3237 string_append (result
, "long double");
3242 APPEND_BLANK (result
);
3243 string_append (result
, "double");
3248 APPEND_BLANK (result
);
3249 string_append (result
, "float");
3254 if (!isdigit ((unsigned char)**mangled
))
3261 if (**mangled
== '_')
3265 for (i
= 0; **mangled
!= '_'; ++(*mangled
), ++i
)
3272 strncpy (buf
, *mangled
, 2);
3275 sscanf (buf
, "%x", &dec
);
3276 sprintf (buf
, "int%i_t", dec
);
3277 APPEND_BLANK (result
);
3278 string_append (result
, buf
);
3282 /* An explicit type, such as "6mytype" or "7integer" */
3294 int bindex
= register_Btype (work
);
3296 string_init (&btype
);
3297 if (demangle_class_name (work
, mangled
, &btype
)) {
3298 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3299 APPEND_BLANK (result
);
3300 string_appends (result
, &btype
);
3304 string_delete (&btype
);
3309 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3310 string_appends (result
, &btype
);
3318 return success
? ((int) tk
) : 0;
3322 /* Handle a template's value parameter for HP aCC (extension from ARM)
3323 **mangled points to 'S' or 'U' */
3326 do_hpacc_template_const_value (work
, mangled
, result
)
3327 struct work_stuff
*work
;
3328 const char **mangled
;
3333 if (**mangled
!= 'U' && **mangled
!= 'S')
3336 unsigned_const
= (**mangled
== 'U');
3343 string_append (result
, "-");
3349 /* special case for -2^31 */
3350 string_append (result
, "-2147483648");
3357 /* We have to be looking at an integer now */
3358 if (!(isdigit (**mangled
)))
3361 /* We only deal with integral values for template
3362 parameters -- so it's OK to look only for digits */
3363 while (isdigit (**mangled
))
3365 char_str
[0] = **mangled
;
3366 string_append (result
, char_str
);
3371 string_append (result
, "U");
3373 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3374 with L or LL suffixes. pai/1997-09-03 */
3376 return 1; /* success */
3379 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3380 **mangled is pointing to the 'A' */
3383 do_hpacc_template_literal (work
, mangled
, result
)
3384 struct work_stuff
*work
;
3385 const char **mangled
;
3388 int literal_len
= 0;
3393 if (**mangled
!= 'A')
3398 literal_len
= consume_count (mangled
);
3403 /* Literal parameters are names of arrays, functions, etc. and the
3404 canonical representation uses the address operator */
3405 string_append (result
, "&");
3407 /* Now recursively demangle the literal name */
3408 recurse
= (char *) xmalloc (literal_len
+ 1);
3409 memcpy (recurse
, *mangled
, literal_len
);
3410 recurse
[literal_len
] = '\000';
3412 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3416 string_append (result
, recurse_dem
);
3421 string_appendn (result
, *mangled
, literal_len
);
3423 (*mangled
) += literal_len
;
3430 snarf_numeric_literal (args
, arg
)
3437 string_append (arg
, char_str
);
3440 else if (**args
== '+')
3443 if (!isdigit (**args
))
3446 while (isdigit (**args
))
3448 char_str
[0] = **args
;
3449 string_append (arg
, char_str
);
3456 /* Demangle the next argument, given by MANGLED into RESULT, which
3457 *should be an uninitialized* string. It will be initialized here,
3458 and free'd should anything go wrong. */
3461 do_arg (work
, mangled
, result
)
3462 struct work_stuff
*work
;
3463 const char **mangled
;
3466 /* Remember where we started so that we can record the type, for
3467 non-squangling type remembering. */
3468 const char *start
= *mangled
;
3470 string_init (result
);
3472 if (work
->nrepeats
> 0)
3476 if (work
->previous_argument
== 0)
3479 /* We want to reissue the previous type in this argument list. */
3480 string_appends (result
, work
->previous_argument
);
3484 if (**mangled
== 'n')
3486 /* A squangling-style repeat. */
3488 work
->nrepeats
= consume_count(mangled
);
3490 if (work
->nrepeats
== 0)
3491 /* This was not a repeat count after all. */
3494 if (work
->nrepeats
> 9)
3496 if (**mangled
!= '_')
3497 /* The repeat count should be followed by an '_' in this
3504 /* Now, the repeat is all set up. */
3505 return do_arg (work
, mangled
, result
);
3508 /* Save the result in WORK->previous_argument so that we can find it
3509 if it's repeated. Note that saving START is not good enough: we
3510 do not want to add additional types to the back-referenceable
3511 type vector when processing a repeated type. */
3512 if (work
->previous_argument
)
3513 string_clear (work
->previous_argument
);
3516 work
->previous_argument
= (string
*) xmalloc (sizeof (string
));
3517 string_init (work
->previous_argument
);
3520 if (!do_type (work
, mangled
, work
->previous_argument
))
3523 string_appends (result
, work
->previous_argument
);
3525 remember_type (work
, start
, *mangled
- start
);
3530 remember_type (work
, start
, len
)
3531 struct work_stuff
*work
;
3537 if (work
->forgetting_types
)
3540 if (work
-> ntypes
>= work
-> typevec_size
)
3542 if (work
-> typevec_size
== 0)
3544 work
-> typevec_size
= 3;
3546 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
3550 work
-> typevec_size
*= 2;
3552 = (char **) xrealloc ((char *)work
-> typevec
,
3553 sizeof (char *) * work
-> typevec_size
);
3556 tem
= xmalloc (len
+ 1);
3557 memcpy (tem
, start
, len
);
3559 work
-> typevec
[work
-> ntypes
++] = tem
;
3563 /* Remember a K type class qualifier. */
3565 remember_Ktype (work
, start
, len
)
3566 struct work_stuff
*work
;
3572 if (work
-> numk
>= work
-> ksize
)
3574 if (work
-> ksize
== 0)
3578 = (char **) xmalloc (sizeof (char *) * work
-> ksize
);
3584 = (char **) xrealloc ((char *)work
-> ktypevec
,
3585 sizeof (char *) * work
-> ksize
);
3588 tem
= xmalloc (len
+ 1);
3589 memcpy (tem
, start
, len
);
3591 work
-> ktypevec
[work
-> numk
++] = tem
;
3594 /* Register a B code, and get an index for it. B codes are registered
3595 as they are seen, rather than as they are completed, so map<temp<char> >
3596 registers map<temp<char> > as B0, and temp<char> as B1 */
3599 register_Btype (work
)
3600 struct work_stuff
*work
;
3604 if (work
-> numb
>= work
-> bsize
)
3606 if (work
-> bsize
== 0)
3610 = (char **) xmalloc (sizeof (char *) * work
-> bsize
);
3616 = (char **) xrealloc ((char *)work
-> btypevec
,
3617 sizeof (char *) * work
-> bsize
);
3620 ret
= work
-> numb
++;
3621 work
-> btypevec
[ret
] = NULL
;
3625 /* Store a value into a previously registered B code type. */
3628 remember_Btype (work
, start
, len
, index
)
3629 struct work_stuff
*work
;
3635 tem
= xmalloc (len
+ 1);
3636 memcpy (tem
, start
, len
);
3638 work
-> btypevec
[index
] = tem
;
3641 /* Lose all the info related to B and K type codes. */
3643 forget_B_and_K_types (work
)
3644 struct work_stuff
*work
;
3648 while (work
-> numk
> 0)
3650 i
= --(work
-> numk
);
3651 if (work
-> ktypevec
[i
] != NULL
)
3653 free (work
-> ktypevec
[i
]);
3654 work
-> ktypevec
[i
] = NULL
;
3658 while (work
-> numb
> 0)
3660 i
= --(work
-> numb
);
3661 if (work
-> btypevec
[i
] != NULL
)
3663 free (work
-> btypevec
[i
]);
3664 work
-> btypevec
[i
] = NULL
;
3668 /* Forget the remembered types, but not the type vector itself. */
3672 struct work_stuff
*work
;
3676 while (work
-> ntypes
> 0)
3678 i
= --(work
-> ntypes
);
3679 if (work
-> typevec
[i
] != NULL
)
3681 free (work
-> typevec
[i
]);
3682 work
-> typevec
[i
] = NULL
;
3687 /* Process the argument list part of the signature, after any class spec
3688 has been consumed, as well as the first 'F' character (if any). For
3691 "__als__3fooRT0" => process "RT0"
3692 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3694 DECLP must be already initialised, usually non-empty. It won't be freed
3697 Note that g++ differs significantly from ARM and lucid style mangling
3698 with regards to references to previously seen types. For example, given
3699 the source fragment:
3703 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3706 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3707 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3709 g++ produces the names:
3714 while lcc (and presumably other ARM style compilers as well) produces:
3716 foo__FiR3fooT1T2T1T2
3717 __ct__3fooFiR3fooT1T2T1T2
3719 Note that g++ bases its type numbers starting at zero and counts all
3720 previously seen types, while lucid/ARM bases its type numbers starting
3721 at one and only considers types after it has seen the 'F' character
3722 indicating the start of the function args. For lucid/ARM style, we
3723 account for this difference by discarding any previously seen types when
3724 we see the 'F' character, and subtracting one from the type number
3730 demangle_args (work
, mangled
, declp
)
3731 struct work_stuff
*work
;
3732 const char **mangled
;
3742 if (PRINT_ARG_TYPES
)
3744 string_append (declp
, "(");
3745 if (**mangled
== '\0')
3747 string_append (declp
, "void");
3751 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
3752 || work
->nrepeats
> 0)
3754 if ((**mangled
== 'N') || (**mangled
== 'T'))
3756 temptype
= *(*mangled
)++;
3758 if (temptype
== 'N')
3760 if (!get_count (mangled
, &r
))
3769 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
3771 /* If we have 10 or more types we might have more than a 1 digit
3772 index so we'll have to consume the whole count here. This
3773 will lose if the next thing is a type name preceded by a
3774 count but it's impossible to demangle that case properly
3775 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3776 Pc, ...)" or "(..., type12, char *, ...)" */
3777 if ((t
= consume_count(mangled
)) == 0)
3784 if (!get_count (mangled
, &t
))
3789 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
3793 /* Validate the type index. Protect against illegal indices from
3794 malformed type strings. */
3795 if ((t
< 0) || (t
>= work
-> ntypes
))
3799 while (work
->nrepeats
> 0 || --r
>= 0)
3801 tem
= work
-> typevec
[t
];
3802 if (need_comma
&& PRINT_ARG_TYPES
)
3804 string_append (declp
, ", ");
3806 if (!do_arg (work
, &tem
, &arg
))
3810 if (PRINT_ARG_TYPES
)
3812 string_appends (declp
, &arg
);
3814 string_delete (&arg
);
3820 if (need_comma
&& PRINT_ARG_TYPES
)
3821 string_append (declp
, ", ");
3822 if (!do_arg (work
, mangled
, &arg
))
3824 if (PRINT_ARG_TYPES
)
3825 string_appends (declp
, &arg
);
3826 string_delete (&arg
);
3831 if (**mangled
== 'e')
3834 if (PRINT_ARG_TYPES
)
3838 string_append (declp
, ",");
3840 string_append (declp
, "...");
3844 if (PRINT_ARG_TYPES
)
3846 string_append (declp
, ")");
3851 /* Like demangle_args, but for demangling the argument lists of function
3852 and method pointers or references, not top-level declarations. */
3855 demangle_nested_args (work
, mangled
, declp
)
3856 struct work_stuff
*work
;
3857 const char **mangled
;
3860 string
* saved_previous_argument
;
3864 /* The G++ name-mangling algorithm does not remember types on nested
3865 argument lists, unless -fsquangling is used, and in that case the
3866 type vector updated by remember_type is not used. So, we turn
3867 off remembering of types here. */
3868 ++work
->forgetting_types
;
3870 /* For the repeat codes used with -fsquangling, we must keep track of
3871 the last argument. */
3872 saved_previous_argument
= work
->previous_argument
;
3873 saved_nrepeats
= work
->nrepeats
;
3874 work
->previous_argument
= 0;
3877 /* Actually demangle the arguments. */
3878 result
= demangle_args (work
, mangled
, declp
);
3880 /* Restore the previous_argument field. */
3881 if (work
->previous_argument
)
3882 string_delete (work
->previous_argument
);
3883 work
->previous_argument
= saved_previous_argument
;
3884 work
->nrepeats
= saved_nrepeats
;
3890 demangle_function_name (work
, mangled
, declp
, scan
)
3891 struct work_stuff
*work
;
3892 const char **mangled
;
3900 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
3901 string_need (declp
, 1);
3902 *(declp
-> p
) = '\0';
3904 /* Consume the function name, including the "__" separating the name
3905 from the signature. We are guaranteed that SCAN points to the
3908 (*mangled
) = scan
+ 2;
3909 /* We may be looking at an instantiation of a template function:
3910 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
3911 following _F marks the start of the function arguments. Handle
3912 the template arguments first. */
3914 if (HP_DEMANGLING
&& (**mangled
== 'X'))
3916 demangle_arm_hp_template (work
, mangled
, 0, declp
);
3917 /* This leaves MANGLED pointing to the 'F' marking func args */
3920 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
3923 /* See if we have an ARM style constructor or destructor operator.
3924 If so, then just record it, clear the decl, and return.
3925 We can't build the actual constructor/destructor decl until later,
3926 when we recover the class name from the signature. */
3928 if (strcmp (declp
-> b
, "__ct") == 0)
3930 work
-> constructor
+= 1;
3931 string_clear (declp
);
3934 else if (strcmp (declp
-> b
, "__dt") == 0)
3936 work
-> destructor
+= 1;
3937 string_clear (declp
);
3942 if (declp
->p
- declp
->b
>= 3
3943 && declp
->b
[0] == 'o'
3944 && declp
->b
[1] == 'p'
3945 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
3947 /* see if it's an assignment expression */
3948 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
3949 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
3951 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
3953 int len
= declp
->p
- declp
->b
- 10;
3954 if ((int) strlen (optable
[i
].in
) == len
3955 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
3957 string_clear (declp
);
3958 string_append (declp
, "operator");
3959 string_append (declp
, optable
[i
].out
);
3960 string_append (declp
, "=");
3967 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
3969 int len
= declp
->p
- declp
->b
- 3;
3970 if ((int) strlen (optable
[i
].in
) == len
3971 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
3973 string_clear (declp
);
3974 string_append (declp
, "operator");
3975 string_append (declp
, optable
[i
].out
);
3981 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
3982 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
3984 /* type conversion operator */
3986 if (do_type (work
, &tem
, &type
))
3988 string_clear (declp
);
3989 string_append (declp
, "operator ");
3990 string_appends (declp
, &type
);
3991 string_delete (&type
);
3994 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
3995 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
3998 /* type conversion operator. */
4000 if (do_type (work
, &tem
, &type
))
4002 string_clear (declp
);
4003 string_append (declp
, "operator ");
4004 string_appends (declp
, &type
);
4005 string_delete (&type
);
4008 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4009 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
4010 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
4012 if (declp
->b
[4] == '\0')
4015 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4017 if (strlen (optable
[i
].in
) == 2
4018 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4020 string_clear (declp
);
4021 string_append (declp
, "operator");
4022 string_append (declp
, optable
[i
].out
);
4029 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4032 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4034 if (strlen (optable
[i
].in
) == 3
4035 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4037 string_clear (declp
);
4038 string_append (declp
, "operator");
4039 string_append (declp
, optable
[i
].out
);
4048 /* a mini string-handling package */
4063 s
->p
= s
->b
= xmalloc (n
);
4066 else if (s
->e
- s
->p
< n
)
4071 s
->b
= xrealloc (s
->b
, n
);
4084 s
->b
= s
->e
= s
->p
= NULL
;
4092 s
->b
= s
->p
= s
->e
= NULL
;
4108 return (s
->b
== s
->p
);
4114 string_append (p
, s
)
4119 if (s
== NULL
|| *s
== '\0')
4123 memcpy (p
->p
, s
, n
);
4128 string_appends (p
, s
)
4137 memcpy (p
->p
, s
->b
, n
);
4143 string_appendn (p
, s
, n
)
4151 memcpy (p
->p
, s
, n
);
4157 string_prepend (p
, s
)
4161 if (s
!= NULL
&& *s
!= '\0')
4163 string_prependn (p
, s
, strlen (s
));
4168 string_prepends (p
, s
)
4173 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4178 string_prependn (p
, s
, n
)
4188 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4192 memcpy (p
->b
, s
, n
);
4197 /* To generate a standalone demangler program for testing purposes,
4198 just compile and link this file with -DMAIN and libiberty.a. When
4199 run, it demangles each command line arg, or each stdin string, and
4200 prints the result on stdout. */
4206 static char *program_name
;
4207 static char *program_version
= VERSION
;
4208 static int flags
= DMGL_PARAMS
| DMGL_ANSI
;
4210 static void demangle_it
PARAMS ((char *));
4211 static void usage
PARAMS ((FILE *, int));
4212 static void fatal
PARAMS ((char *));
4215 demangle_it (mangled_name
)
4220 result
= cplus_demangle (mangled_name
, flags
);
4223 printf ("%s\n", mangled_name
);
4227 printf ("%s\n", result
);
4233 usage (stream
, status
)
4238 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4239 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4240 [--help] [--version] [arg...]\n",
4245 #define MBUF_SIZE 32767
4246 char mbuffer
[MBUF_SIZE
];
4248 /* Defined in the automatically-generated underscore.c. */
4249 extern int prepends_underscore
;
4251 int strip_underscore
= 0;
4253 static struct option long_options
[] = {
4254 {"strip-underscores", no_argument
, 0, '_'},
4255 {"format", required_argument
, 0, 's'},
4256 {"help", no_argument
, 0, 'h'},
4257 {"no-strip-underscores", no_argument
, 0, 'n'},
4258 {"version", no_argument
, 0, 'v'},
4259 {0, no_argument
, 0, 0}
4262 /* More 'friendly' abort that prints the line and file.
4263 config.h can #define abort fancy_abort if you like that sort of thing. */
4268 fatal ("Internal gcc abort.");
4279 program_name
= argv
[0];
4281 strip_underscore
= prepends_underscore
;
4283 while ((c
= getopt_long (argc
, argv
, "_ns:j", long_options
, (int *) 0)) != EOF
)
4293 strip_underscore
= 0;
4296 printf ("GNU %s (C++ demangler), version %s\n", program_name
, program_version
);
4299 strip_underscore
= 1;
4302 if (strcmp (optarg
, "gnu") == 0)
4304 current_demangling_style
= gnu_demangling
;
4306 else if (strcmp (optarg
, "lucid") == 0)
4308 current_demangling_style
= lucid_demangling
;
4310 else if (strcmp (optarg
, "arm") == 0)
4312 current_demangling_style
= arm_demangling
;
4314 else if (strcmp (optarg
, "hp") == 0)
4316 current_demangling_style
= hp_demangling
;
4318 else if (strcmp (optarg
, "edg") == 0)
4320 current_demangling_style
= edg_demangling
;
4324 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
4325 program_name
, optarg
);
4334 for ( ; optind
< argc
; optind
++)
4336 demangle_it (argv
[optind
]);
4345 /* Try to read a label. */
4346 while (c
!= EOF
&& (isalnum(c
) || c
== '_' || c
== '$' || c
== '.' ||
4347 c
== '<' || c
== '>' || c
== '#' || c
== ',' || c
== '*' || c
== '&' ||
4348 c
== '[' || c
== ']' || c
== ':' || c
== '(' || c
== ')'))
4349 /* the ones in the 2nd & 3rd lines were added to handle
4350 HP aCC template specialization manglings */
4352 if (i
>= MBUF_SIZE
-1)
4361 if (mbuffer
[0] == '.')
4363 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
4371 result
= cplus_demangle (mbuffer
+ skip_first
, flags
);
4374 if (mbuffer
[0] == '.')
4376 fputs (result
, stdout
);
4380 fputs (mbuffer
, stdout
);
4397 fprintf (stderr
, "%s: %s\n", program_name
, str
);
4405 register PTR value
= (PTR
) malloc (size
);
4407 fatal ("virtual memory exhausted");
4412 xrealloc (ptr
, size
)
4416 register PTR value
= (PTR
) realloc (ptr
, size
);
4418 fatal ("virtual memory exhausted");