1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 Libiberty is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with libiberty; see the file COPYING.LIB. If
20 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
25 This file imports xmalloc and xrealloc, which are like malloc and
26 realloc except that they generate a fatal error if there is no
29 /* This file lives in both GCC and libiberty. When making changes, please
30 try not to break either. */
37 #include <sys/types.h>
49 #undef CURRENT_DEMANGLING_STYLE
50 #define CURRENT_DEMANGLING_STYLE work->options
52 #include "libiberty.h"
54 static const char *mystrstr
PARAMS ((const char *, const char *));
60 register const char *p
= s1
;
61 register int len
= strlen (s2
);
63 for (; (p
= strchr (p
, *s2
)) != 0; p
++)
65 if (strncmp (p
, s2
, len
) == 0)
73 /* In order to allow a single demangler executable to demangle strings
74 using various common values of CPLUS_MARKER, as well as any specific
75 one set at compile time, we maintain a string containing all the
76 commonly used ones, and check to see if the marker we are looking for
77 is in that string. CPLUS_MARKER is usually '$' on systems where the
78 assembler can deal with that. Where the assembler can't, it's usually
79 '.' (but on many systems '.' is used for other things). We put the
80 current defined CPLUS_MARKER first (which defaults to '$'), followed
81 by the next most common value, followed by an explicit '$' in case
82 the value of CPLUS_MARKER is not '$'.
84 We could avoid this if we could just get g++ to tell us what the actual
85 cplus marker character is as part of the debug information, perhaps by
86 ensuring that it is the character that terminates the gcc<n>_compiled
87 marker symbol (FIXME). */
89 #if !defined (CPLUS_MARKER)
90 #define CPLUS_MARKER '$'
93 enum demangling_styles current_demangling_style
= gnu_demangling
;
95 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
97 static char char_str
[2] = { '\000', '\000' };
100 set_cplus_marker_for_demangling (ch
)
103 cplus_markers
[0] = ch
;
106 typedef struct string
/* Beware: these aren't required to be */
107 { /* '\0' terminated. */
108 char *b
; /* pointer to start of string */
109 char *p
; /* pointer after last character */
110 char *e
; /* pointer after end of allocated space */
113 /* Stuff that is shared between sub-routines.
114 Using a shared structure allows cplus_demangle to be reentrant. */
130 int static_type
; /* A static member function */
131 int temp_start
; /* index in demangled to start of template args */
132 int type_quals
; /* The type qualifiers. */
133 int dllimported
; /* Symbol imported from a PE DLL */
134 char **tmpl_argvec
; /* Template function arguments. */
135 int ntmpl_args
; /* The number of template function arguments. */
136 int forgetting_types
; /* Nonzero if we are not remembering the types
138 string
* previous_argument
; /* The last function argument demangled. */
139 int nrepeats
; /* The number of times to repeat the previous
143 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
144 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
146 static const struct optable
152 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
153 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
154 {"new", " new", 0}, /* old (1.91, and 1.x) */
155 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
156 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
157 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
158 {"as", "=", DMGL_ANSI
}, /* ansi */
159 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
160 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
161 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
162 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
163 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
164 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
165 {"plus", "+", 0}, /* old */
166 {"pl", "+", DMGL_ANSI
}, /* ansi */
167 {"apl", "+=", DMGL_ANSI
}, /* ansi */
168 {"minus", "-", 0}, /* old */
169 {"mi", "-", DMGL_ANSI
}, /* ansi */
170 {"ami", "-=", DMGL_ANSI
}, /* ansi */
171 {"mult", "*", 0}, /* old */
172 {"ml", "*", DMGL_ANSI
}, /* ansi */
173 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
174 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
175 {"convert", "+", 0}, /* old (unary +) */
176 {"negate", "-", 0}, /* old (unary -) */
177 {"trunc_mod", "%", 0}, /* old */
178 {"md", "%", DMGL_ANSI
}, /* ansi */
179 {"amd", "%=", DMGL_ANSI
}, /* ansi */
180 {"trunc_div", "/", 0}, /* old */
181 {"dv", "/", DMGL_ANSI
}, /* ansi */
182 {"adv", "/=", DMGL_ANSI
}, /* ansi */
183 {"truth_andif", "&&", 0}, /* old */
184 {"aa", "&&", DMGL_ANSI
}, /* ansi */
185 {"truth_orif", "||", 0}, /* old */
186 {"oo", "||", DMGL_ANSI
}, /* ansi */
187 {"truth_not", "!", 0}, /* old */
188 {"nt", "!", DMGL_ANSI
}, /* ansi */
189 {"postincrement","++", 0}, /* old */
190 {"pp", "++", DMGL_ANSI
}, /* ansi */
191 {"postdecrement","--", 0}, /* old */
192 {"mm", "--", DMGL_ANSI
}, /* ansi */
193 {"bit_ior", "|", 0}, /* old */
194 {"or", "|", DMGL_ANSI
}, /* ansi */
195 {"aor", "|=", DMGL_ANSI
}, /* ansi */
196 {"bit_xor", "^", 0}, /* old */
197 {"er", "^", DMGL_ANSI
}, /* ansi */
198 {"aer", "^=", DMGL_ANSI
}, /* ansi */
199 {"bit_and", "&", 0}, /* old */
200 {"ad", "&", DMGL_ANSI
}, /* ansi */
201 {"aad", "&=", DMGL_ANSI
}, /* ansi */
202 {"bit_not", "~", 0}, /* old */
203 {"co", "~", DMGL_ANSI
}, /* ansi */
204 {"call", "()", 0}, /* old */
205 {"cl", "()", DMGL_ANSI
}, /* ansi */
206 {"alshift", "<<", 0}, /* old */
207 {"ls", "<<", DMGL_ANSI
}, /* ansi */
208 {"als", "<<=", DMGL_ANSI
}, /* ansi */
209 {"arshift", ">>", 0}, /* old */
210 {"rs", ">>", DMGL_ANSI
}, /* ansi */
211 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
212 {"component", "->", 0}, /* old */
213 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
214 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
215 {"indirect", "*", 0}, /* old */
216 {"method_call", "->()", 0}, /* old */
217 {"addr", "&", 0}, /* old (unary &) */
218 {"array", "[]", 0}, /* old */
219 {"vc", "[]", DMGL_ANSI
}, /* ansi */
220 {"compound", ", ", 0}, /* old */
221 {"cm", ", ", DMGL_ANSI
}, /* ansi */
222 {"cond", "?:", 0}, /* old */
223 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
224 {"max", ">?", 0}, /* old */
225 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
226 {"min", "<?", 0}, /* old */
227 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
228 {"nop", "", 0}, /* old (for operator=) */
229 {"rm", "->*", DMGL_ANSI
}, /* ansi */
230 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
233 /* These values are used to indicate the various type varieties.
234 They are all non-zero so that they can be used as `success'
236 typedef enum type_kind_t
247 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
248 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
249 string_prepend(str, " ");}
250 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
251 string_append(str, " ");}
252 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
254 /* The scope separator appropriate for the language being demangled. */
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_class_name
PARAMS ((struct work_stuff
*, const char **, string
*));
292 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
296 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
299 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
302 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
305 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
308 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
311 arm_special
PARAMS ((const char **, string
*));
314 string_need
PARAMS ((string
*, int));
317 string_delete
PARAMS ((string
*));
320 string_init
PARAMS ((string
*));
323 string_clear
PARAMS ((string
*));
327 string_empty
PARAMS ((string
*));
331 string_append
PARAMS ((string
*, const char *));
334 string_appends
PARAMS ((string
*, string
*));
337 string_appendn
PARAMS ((string
*, const char *, int));
340 string_prepend
PARAMS ((string
*, const char *));
343 string_prependn
PARAMS ((string
*, const char *, int));
346 get_count
PARAMS ((const char **, int *));
349 consume_count
PARAMS ((const char **));
352 consume_count_with_underscores
PARAMS ((const char**));
355 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
358 demangle_nested_args
PARAMS ((struct work_stuff
*, const char**, string
*));
361 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
364 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
367 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
371 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
374 remember_Btype
PARAMS ((struct work_stuff
*, const char *, int, int));
377 register_Btype
PARAMS ((struct work_stuff
*));
380 remember_Ktype
PARAMS ((struct work_stuff
*, const char *, int));
383 forget_types
PARAMS ((struct work_stuff
*));
386 forget_B_and_K_types
PARAMS ((struct work_stuff
*));
389 string_prepends
PARAMS ((string
*, string
*));
392 demangle_template_value_parm
PARAMS ((struct work_stuff
*, const char**,
393 string
*, type_kind_t
));
396 do_hpacc_template_const_value
PARAMS ((struct work_stuff
*, const char **, string
*));
399 do_hpacc_template_literal
PARAMS ((struct work_stuff
*, const char **, string
*));
402 snarf_numeric_literal
PARAMS ((const char **, string
*));
404 /* There is a TYPE_QUAL value for each type qualifier. They can be
405 combined by bitwise-or to form the complete set of qualifiers for a
408 #define TYPE_UNQUALIFIED 0x0
409 #define TYPE_QUAL_CONST 0x1
410 #define TYPE_QUAL_VOLATILE 0x2
411 #define TYPE_QUAL_RESTRICT 0x4
414 code_for_qualifier
PARAMS ((int));
417 qualifier_string
PARAMS ((int));
420 demangle_qualifier
PARAMS ((int));
422 /* Translate count to integer, consuming tokens in the process.
423 Conversion terminates on the first non-digit character.
424 Trying to consume something that isn't a count results in
425 no consumption of input and a return of 0. */
431 unsigned int count
= 0;
434 while (isdigit ((unsigned char)**type
))
437 count
+= **type
- '0';
438 /* A sanity check. Otherwise a symbol like
439 `_Utf390_1__1_9223372036854775807__9223372036854775'
440 can cause this function to return a negative value.
441 In this case we just consume until the end of the string. */
442 if (count
> strlen (*type
))
453 /* Like consume_count, but for counts that are preceded and followed
454 by '_' if they are greater than 10. Also, -1 is returned for
455 failure, since 0 can be a valid value. */
458 consume_count_with_underscores (mangled
)
459 const char **mangled
;
463 if (**mangled
== '_')
466 if (!isdigit ((unsigned char)**mangled
))
469 idx
= consume_count (mangled
);
470 if (**mangled
!= '_')
471 /* The trailing underscore was missing. */
478 if (**mangled
< '0' || **mangled
> '9')
481 idx
= **mangled
- '0';
488 /* C is the code for a type-qualifier. Return the TYPE_QUAL
489 corresponding to this qualifier. */
492 code_for_qualifier (c
)
498 return TYPE_QUAL_CONST
;
501 return TYPE_QUAL_VOLATILE
;
504 return TYPE_QUAL_RESTRICT
;
510 /* C was an invalid qualifier. */
514 /* Return the string corresponding to the qualifiers given by
518 qualifier_string (type_quals
)
523 case TYPE_UNQUALIFIED
:
526 case TYPE_QUAL_CONST
:
529 case TYPE_QUAL_VOLATILE
:
532 case TYPE_QUAL_RESTRICT
:
535 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
536 return "const volatile";
538 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
539 return "const __restrict";
541 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
542 return "volatile __restrict";
544 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
545 return "const volatile __restrict";
551 /* TYPE_QUALS was an invalid qualifier set. */
555 /* C is the code for a type-qualifier. Return the string
556 corresponding to this qualifier. This function should only be
557 called with a valid qualifier code. */
560 demangle_qualifier (c
)
563 return qualifier_string (code_for_qualifier (c
));
567 cplus_demangle_opname (opname
, result
, options
)
574 struct work_stuff work
[1];
577 len
= strlen(opname
);
580 memset ((char *) work
, 0, sizeof (work
));
581 work
->options
= options
;
583 if (opname
[0] == '_' && opname
[1] == '_'
584 && opname
[2] == 'o' && opname
[3] == 'p')
587 /* type conversion operator. */
589 if (do_type (work
, &tem
, &type
))
591 strcat (result
, "operator ");
592 strncat (result
, type
.b
, type
.p
- type
.b
);
593 string_delete (&type
);
597 else if (opname
[0] == '_' && opname
[1] == '_'
598 && opname
[2] >= 'a' && opname
[2] <= 'z'
599 && opname
[3] >= 'a' && opname
[3] <= 'z')
601 if (opname
[4] == '\0')
605 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
607 if (strlen (optable
[i
].in
) == 2
608 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
610 strcat (result
, "operator");
611 strcat (result
, optable
[i
].out
);
619 if (opname
[2] == 'a' && opname
[5] == '\0')
623 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
625 if (strlen (optable
[i
].in
) == 3
626 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
628 strcat (result
, "operator");
629 strcat (result
, optable
[i
].out
);
640 && strchr (cplus_markers
, opname
[2]) != NULL
)
642 /* see if it's an assignment expression */
643 if (len
>= 10 /* op$assign_ */
644 && memcmp (opname
+ 3, "assign_", 7) == 0)
647 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
650 if ((int) strlen (optable
[i
].in
) == len1
651 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
653 strcat (result
, "operator");
654 strcat (result
, optable
[i
].out
);
655 strcat (result
, "=");
664 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
667 if ((int) strlen (optable
[i
].in
) == len1
668 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
670 strcat (result
, "operator");
671 strcat (result
, optable
[i
].out
);
678 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
679 && strchr (cplus_markers
, opname
[4]) != NULL
)
681 /* type conversion operator */
683 if (do_type (work
, &tem
, &type
))
685 strcat (result
, "operator ");
686 strncat (result
, type
.b
, type
.p
- type
.b
);
687 string_delete (&type
);
691 squangle_mop_up (work
);
695 /* Takes operator name as e.g. "++" and returns mangled
696 operator name (e.g. "postincrement_expr"), or NULL if not found.
698 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
699 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
702 cplus_mangle_opname (opname
, options
)
709 len
= strlen (opname
);
710 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
712 if ((int) strlen (optable
[i
].out
) == len
713 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
714 && memcmp (optable
[i
].out
, opname
, len
) == 0)
715 return optable
[i
].in
;
720 /* char *cplus_demangle (const char *mangled, int options)
722 If MANGLED is a mangled function name produced by GNU C++, then
723 a pointer to a malloced string giving a C++ representation
724 of the name will be returned; otherwise NULL will be returned.
725 It is the caller's responsibility to free the string which
728 The OPTIONS arg may contain one or more of the following bits:
730 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
732 DMGL_PARAMS Function parameters are included.
736 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
737 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
738 cplus_demangle ("foo__1Ai", 0) => "A::foo"
740 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
741 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
742 cplus_demangle ("foo__1Afe", 0) => "A::foo"
744 Note that any leading underscores, or other such characters prepended by
745 the compilation system, are presumed to have already been stripped from
749 cplus_demangle (mangled
, options
)
754 struct work_stuff work
[1];
755 memset ((char *) work
, 0, sizeof (work
));
756 work
-> options
= options
;
757 if ((work
-> options
& DMGL_STYLE_MASK
) == 0)
758 work
-> options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
760 ret
= internal_cplus_demangle (work
, mangled
);
761 squangle_mop_up (work
);
766 /* This function performs most of what cplus_demangle use to do, but
767 to be able to demangle a name with a B, K or n code, we need to
768 have a longer term memory of what types have been seen. The original
769 now intializes and cleans up the squangle code info, while internal
770 calls go directly to this routine to avoid resetting that info. */
773 internal_cplus_demangle (work
, mangled
)
774 struct work_stuff
*work
;
780 char *demangled
= NULL
;
782 s1
= work
->constructor
;
783 s2
= work
->destructor
;
784 s3
= work
->static_type
;
785 s4
= work
->type_quals
;
786 work
->constructor
= work
->destructor
= 0;
787 work
->type_quals
= TYPE_UNQUALIFIED
;
788 work
->dllimported
= 0;
790 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
794 /* First check to see if gnu style demangling is active and if the
795 string to be demangled contains a CPLUS_MARKER. If so, attempt to
796 recognize one of the gnu special forms rather than looking for a
797 standard prefix. In particular, don't worry about whether there
798 is a "__" string in the mangled string. Consider "_$_5__foo" for
801 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
803 success
= gnu_special (work
, &mangled
, &decl
);
807 success
= demangle_prefix (work
, &mangled
, &decl
);
809 if (success
&& (*mangled
!= '\0'))
811 success
= demangle_signature (work
, &mangled
, &decl
);
813 if (work
->constructor
== 2)
815 string_prepend (&decl
, "global constructors keyed to ");
816 work
->constructor
= 0;
818 else if (work
->destructor
== 2)
820 string_prepend (&decl
, "global destructors keyed to ");
821 work
->destructor
= 0;
823 else if (work
->dllimported
== 1)
825 string_prepend (&decl
, "import stub for ");
826 work
->dllimported
= 0;
828 demangled
= mop_up (work
, &decl
, success
);
830 work
->constructor
= s1
;
831 work
->destructor
= s2
;
832 work
->static_type
= s3
;
833 work
->type_quals
= s4
;
838 /* Clear out and squangling related storage */
840 squangle_mop_up (work
)
841 struct work_stuff
*work
;
843 /* clean up the B and K type mangling types. */
844 forget_B_and_K_types (work
);
845 if (work
-> btypevec
!= NULL
)
847 free ((char *) work
-> btypevec
);
849 if (work
-> ktypevec
!= NULL
)
851 free ((char *) work
-> ktypevec
);
855 /* Clear out any mangled storage */
858 mop_up (work
, declp
, success
)
859 struct work_stuff
*work
;
863 char *demangled
= NULL
;
865 /* Discard the remembered types, if any. */
868 if (work
-> typevec
!= NULL
)
870 free ((char *) work
-> typevec
);
871 work
-> typevec
= NULL
;
873 if (work
->tmpl_argvec
)
877 for (i
= 0; i
< work
->ntmpl_args
; i
++)
878 if (work
->tmpl_argvec
[i
])
879 free ((char*) work
->tmpl_argvec
[i
]);
881 free ((char*) work
->tmpl_argvec
);
882 work
->tmpl_argvec
= NULL
;
884 if (work
->previous_argument
)
886 string_delete (work
->previous_argument
);
887 free ((char*) work
->previous_argument
);
888 work
->previous_argument
= NULL
;
891 /* If demangling was successful, ensure that the demangled string is null
892 terminated and return it. Otherwise, free the demangling decl. */
896 string_delete (declp
);
900 string_appendn (declp
, "", 1);
901 demangled
= declp
-> b
;
910 demangle_signature -- demangle the signature part of a mangled name
915 demangle_signature (struct work_stuff *work, const char **mangled,
920 Consume and demangle the signature portion of the mangled name.
922 DECLP is the string where demangled output is being built. At
923 entry it contains the demangled root name from the mangled name
924 prefix. I.E. either a demangled operator name or the root function
925 name. In some special cases, it may contain nothing.
927 *MANGLED points to the current unconsumed location in the mangled
928 name. As tokens are consumed and demangling is performed, the
929 pointer is updated to continuously point at the next token to
932 Demangling GNU style mangled names is nasty because there is no
933 explicit token that marks the start of the outermost function
937 demangle_signature (work
, mangled
, declp
)
938 struct work_stuff
*work
;
939 const char **mangled
;
945 int expect_return_type
= 0;
946 const char *oldmangled
= NULL
;
950 while (success
&& (**mangled
!= '\0'))
955 oldmangled
= *mangled
;
956 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
958 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
959 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
965 oldmangled
= *mangled
;
966 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
967 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
975 /* Static member function */
976 if (oldmangled
== NULL
)
978 oldmangled
= *mangled
;
981 work
-> static_type
= 1;
987 work
->type_quals
|= code_for_qualifier (**mangled
);
989 /* a qualified member function */
990 if (oldmangled
== NULL
)
991 oldmangled
= *mangled
;
996 /* Local class name follows after "Lnnn_" */
999 while (**mangled
&& (**mangled
!= '_'))
1010 case '0': case '1': case '2': case '3': case '4':
1011 case '5': case '6': case '7': case '8': case '9':
1012 if (oldmangled
== NULL
)
1014 oldmangled
= *mangled
;
1016 work
->temp_start
= -1; /* uppermost call to demangle_class */
1017 success
= demangle_class (work
, mangled
, declp
);
1020 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1022 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1024 /* EDG and others will have the "F", so we let the loop cycle
1025 if we are looking at one. */
1026 if (**mangled
!= 'F')
1035 success
= do_type (work
, mangled
, &s
);
1038 string_append (&s
, SCOPE_STRING (work
));
1039 string_prepends (declp
, &s
);
1048 /* ARM/HP style demangling includes a specific 'F' character after
1049 the class name. For GNU style, it is just implied. So we can
1050 safely just consume any 'F' at this point and be compatible
1051 with either style. */
1057 /* For lucid/ARM/HP style we have to forget any types we might
1058 have remembered up to this point, since they were not argument
1059 types. GNU style considers all types seen as available for
1060 back references. See comment in demangle_args() */
1062 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1064 forget_types (work
);
1066 success
= demangle_args (work
, mangled
, declp
);
1067 /* After picking off the function args, we expect to either
1068 find the function return type (preceded by an '_') or the
1069 end of the string. */
1070 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1073 /* At this level, we do not care about the return type. */
1074 success
= do_type (work
, mangled
, &tname
);
1075 string_delete (&tname
);
1082 string_init(&trawname
);
1083 string_init(&tname
);
1084 if (oldmangled
== NULL
)
1086 oldmangled
= *mangled
;
1088 success
= demangle_template (work
, mangled
, &tname
,
1092 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1094 string_append (&tname
, SCOPE_STRING (work
));
1096 string_prepends(declp
, &tname
);
1097 if (work
-> destructor
& 1)
1099 string_prepend (&trawname
, "~");
1100 string_appends (declp
, &trawname
);
1101 work
->destructor
-= 1;
1103 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1105 string_appends (declp
, &trawname
);
1106 work
->constructor
-= 1;
1108 string_delete(&trawname
);
1109 string_delete(&tname
);
1115 if (GNU_DEMANGLING
&& expect_return_type
)
1117 /* Read the return type. */
1119 string_init (&return_type
);
1122 success
= do_type (work
, mangled
, &return_type
);
1123 APPEND_BLANK (&return_type
);
1125 string_prepends (declp
, &return_type
);
1126 string_delete (&return_type
);
1130 /* At the outermost level, we cannot have a return type specified,
1131 so if we run into another '_' at this point we are dealing with
1132 a mangled name that is either bogus, or has been mangled by
1133 some algorithm we don't know how to deal with. So just
1134 reject the entire demangling. */
1135 /* However, "_nnn" is an expected suffix for alternate entry point
1136 numbered nnn for a function, with HP aCC, so skip over that
1137 without reporting failure. pai/1997-09-04 */
1141 while (**mangled
&& isdigit ((unsigned char)**mangled
))
1151 /* A G++ template function. Read the template arguments. */
1152 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1154 if (!(work
->constructor
& 1))
1155 expect_return_type
= 1;
1164 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1166 /* Assume we have stumbled onto the first outermost function
1167 argument token, and start processing args. */
1169 success
= demangle_args (work
, mangled
, declp
);
1173 /* Non-GNU demanglers use a specific token to mark the start
1174 of the outermost function argument tokens. Typically 'F',
1175 for ARM/HP-demangling, for example. So if we find something
1176 we are not prepared for, it must be an error. */
1182 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1185 if (success
&& expect_func
)
1188 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1190 forget_types (work
);
1192 success
= demangle_args (work
, mangled
, declp
);
1193 /* Since template include the mangling of their return types,
1194 we must set expect_func to 0 so that we don't try do
1195 demangle more arguments the next time we get here. */
1200 if (success
&& !func_done
)
1202 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1204 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1205 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1206 first case, and need to ensure that the '(void)' gets added to
1207 the current declp. Note that with ARM/HP, the first case
1208 represents the name of a static data member 'foo::bar',
1209 which is in the current declp, so we leave it alone. */
1210 success
= demangle_args (work
, mangled
, declp
);
1213 if (success
&& PRINT_ARG_TYPES
)
1215 if (work
->static_type
)
1216 string_append (declp
, " static");
1217 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1219 APPEND_BLANK (declp
);
1220 string_append (declp
, qualifier_string (work
->type_quals
));
1230 demangle_method_args (work
, mangled
, declp
)
1231 struct work_stuff
*work
;
1232 const char **mangled
;
1237 if (work
-> static_type
)
1239 string_append (declp
, *mangled
+ 1);
1240 *mangled
+= strlen (*mangled
);
1245 success
= demangle_args (work
, mangled
, declp
);
1253 demangle_template_template_parm (work
, mangled
, tname
)
1254 struct work_stuff
*work
;
1255 const char **mangled
;
1264 string_append (tname
, "template <");
1265 /* get size of template parameter list */
1266 if (get_count (mangled
, &r
))
1268 for (i
= 0; i
< r
; i
++)
1272 string_append (tname
, ", ");
1275 /* Z for type parameters */
1276 if (**mangled
== 'Z')
1279 string_append (tname
, "class");
1281 /* z for template parameters */
1282 else if (**mangled
== 'z')
1286 demangle_template_template_parm (work
, mangled
, tname
);
1294 /* temp is initialized in do_type */
1295 success
= do_type (work
, mangled
, &temp
);
1298 string_appends (tname
, &temp
);
1300 string_delete(&temp
);
1310 if (tname
->p
[-1] == '>')
1311 string_append (tname
, " ");
1312 string_append (tname
, "> class");
1317 demangle_integral_value (work
, mangled
, s
)
1318 struct work_stuff
*work
;
1319 const char** mangled
;
1324 if (**mangled
== 'E')
1326 int need_operator
= 0;
1329 string_appendn (s
, "(", 1);
1331 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1340 len
= strlen (*mangled
);
1343 i
< sizeof (optable
) / sizeof (optable
[0]);
1346 size_t l
= strlen (optable
[i
].in
);
1349 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1351 string_appendn (s
, " ", 1);
1352 string_append (s
, optable
[i
].out
);
1353 string_appendn (s
, " ", 1);
1366 success
= demangle_template_value_parm (work
, mangled
, s
,
1370 if (**mangled
!= 'W')
1374 string_appendn (s
, ")", 1);
1378 else if (**mangled
== 'Q' || **mangled
== 'K')
1379 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1384 if (**mangled
== 'm')
1386 string_appendn (s
, "-", 1);
1389 while (isdigit ((unsigned char)**mangled
))
1391 string_appendn (s
, *mangled
, 1);
1401 demangle_template_value_parm (work
, mangled
, s
, tk
)
1402 struct work_stuff
*work
;
1403 const char **mangled
;
1409 if (**mangled
== 'Y')
1411 /* The next argument is a template parameter. */
1415 idx
= consume_count_with_underscores (mangled
);
1417 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1418 || consume_count_with_underscores (mangled
) == -1)
1420 if (work
->tmpl_argvec
)
1421 string_append (s
, work
->tmpl_argvec
[idx
]);
1425 sprintf(buf
, "T%d", idx
);
1426 string_append (s
, buf
);
1429 else if (tk
== tk_integral
)
1430 success
= demangle_integral_value (work
, mangled
, s
);
1431 else if (tk
== tk_char
)
1435 if (**mangled
== 'm')
1437 string_appendn (s
, "-", 1);
1440 string_appendn (s
, "'", 1);
1441 val
= consume_count(mangled
);
1446 string_appendn (s
, &tmp
[0], 1);
1447 string_appendn (s
, "'", 1);
1449 else if (tk
== tk_bool
)
1451 int val
= consume_count (mangled
);
1453 string_appendn (s
, "false", 5);
1455 string_appendn (s
, "true", 4);
1459 else if (tk
== tk_real
)
1461 if (**mangled
== 'm')
1463 string_appendn (s
, "-", 1);
1466 while (isdigit ((unsigned char)**mangled
))
1468 string_appendn (s
, *mangled
, 1);
1471 if (**mangled
== '.') /* fraction */
1473 string_appendn (s
, ".", 1);
1475 while (isdigit ((unsigned char)**mangled
))
1477 string_appendn (s
, *mangled
, 1);
1481 if (**mangled
== 'e') /* exponent */
1483 string_appendn (s
, "e", 1);
1485 while (isdigit ((unsigned char)**mangled
))
1487 string_appendn (s
, *mangled
, 1);
1492 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1494 int symbol_len
= consume_count (mangled
);
1495 if (symbol_len
== 0)
1497 if (symbol_len
== 0)
1498 string_appendn (s
, "0", 1);
1501 char *p
= xmalloc (symbol_len
+ 1), *q
;
1502 strncpy (p
, *mangled
, symbol_len
);
1503 p
[symbol_len
] = '\0';
1504 /* We use cplus_demangle here, rather than
1505 internal_cplus_demangle, because the name of the entity
1506 mangled here does not make use of any of the squangling
1507 or type-code information we have built up thus far; it is
1508 mangled independently. */
1509 q
= cplus_demangle (p
, work
->options
);
1510 if (tk
== tk_pointer
)
1511 string_appendn (s
, "&", 1);
1512 /* FIXME: Pointer-to-member constants should get a
1513 qualifying class name here. */
1516 string_append (s
, q
);
1520 string_append (s
, p
);
1523 *mangled
+= symbol_len
;
1529 /* Demangle the template name in MANGLED. The full name of the
1530 template (e.g., S<int>) is placed in TNAME. The name without the
1531 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1532 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1533 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1534 the tmeplate is remembered in the list of back-referenceable
1538 demangle_template (work
, mangled
, tname
, trawname
, is_type
, remember
)
1539 struct work_stuff
*work
;
1540 const char **mangled
;
1558 bindex
= register_Btype (work
);
1560 /* get template name */
1561 if (**mangled
== 'z')
1567 idx
= consume_count_with_underscores (mangled
);
1569 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1570 || consume_count_with_underscores (mangled
) == -1)
1573 if (work
->tmpl_argvec
)
1575 string_append (tname
, work
->tmpl_argvec
[idx
]);
1577 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1582 sprintf(buf
, "T%d", idx
);
1583 string_append (tname
, buf
);
1585 string_append (trawname
, buf
);
1590 if ((r
= consume_count (mangled
)) == 0
1591 || (int) strlen (*mangled
) < r
)
1595 string_appendn (tname
, *mangled
, r
);
1597 string_appendn (trawname
, *mangled
, r
);
1601 string_append (tname
, "<");
1602 /* get size of template parameter list */
1603 if (!get_count (mangled
, &r
))
1609 /* Create an array for saving the template argument values. */
1610 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
1611 work
->ntmpl_args
= r
;
1612 for (i
= 0; i
< r
; i
++)
1613 work
->tmpl_argvec
[i
] = 0;
1615 for (i
= 0; i
< r
; i
++)
1619 string_append (tname
, ", ");
1621 /* Z for type parameters */
1622 if (**mangled
== 'Z')
1625 /* temp is initialized in do_type */
1626 success
= do_type (work
, mangled
, &temp
);
1629 string_appends (tname
, &temp
);
1633 /* Save the template argument. */
1634 int len
= temp
.p
- temp
.b
;
1635 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1636 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
1637 work
->tmpl_argvec
[i
][len
] = '\0';
1640 string_delete(&temp
);
1646 /* z for template parameters */
1647 else if (**mangled
== 'z')
1651 success
= demangle_template_template_parm (work
, mangled
, tname
);
1654 && (r2
= consume_count (mangled
)) > 0
1655 && (int) strlen (*mangled
) >= r2
)
1657 string_append (tname
, " ");
1658 string_appendn (tname
, *mangled
, r2
);
1661 /* Save the template argument. */
1663 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1664 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
1665 work
->tmpl_argvec
[i
][len
] = '\0';
1679 /* otherwise, value parameter */
1681 /* temp is initialized in do_type */
1682 success
= do_type (work
, mangled
, &temp
);
1683 string_delete(&temp
);
1695 success
= demangle_template_value_parm (work
, mangled
, s
,
1696 (type_kind_t
) success
);
1708 int len
= s
->p
- s
->b
;
1709 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1710 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
1711 work
->tmpl_argvec
[i
][len
] = '\0';
1713 string_appends (tname
, s
);
1720 if (tname
->p
[-1] == '>')
1721 string_append (tname
, " ");
1722 string_append (tname
, ">");
1725 if (is_type
&& remember
)
1726 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
1729 if (work -> static_type)
1731 string_append (declp, *mangled + 1);
1732 *mangled += strlen (*mangled);
1737 success = demangle_args (work, mangled, declp);
1745 arm_pt (work
, mangled
, n
, anchor
, args
)
1746 struct work_stuff
*work
;
1747 const char *mangled
;
1749 const char **anchor
, **args
;
1751 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1752 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1753 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= mystrstr (mangled
, "__pt__")))
1756 *args
= *anchor
+ 6;
1757 len
= consume_count (args
);
1758 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1764 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
1766 if ((*anchor
= mystrstr (mangled
, "__tm__"))
1767 || (*anchor
= mystrstr (mangled
, "__ps__"))
1768 || (*anchor
= mystrstr (mangled
, "__pt__")))
1771 *args
= *anchor
+ 6;
1772 len
= consume_count (args
);
1773 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1779 else if ((*anchor
= mystrstr (mangled
, "__S")))
1782 *args
= *anchor
+ 3;
1783 len
= consume_count (args
);
1784 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1796 demangle_arm_hp_template (work
, mangled
, n
, declp
)
1797 struct work_stuff
*work
;
1798 const char **mangled
;
1804 const char *e
= *mangled
+ n
;
1807 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1809 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
1811 char *start_spec_args
= NULL
;
1813 /* First check for and omit template specialization pseudo-arguments,
1814 such as in "Spec<#1,#1.*>" */
1815 start_spec_args
= strchr (*mangled
, '<');
1816 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
1817 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
1819 string_appendn (declp
, *mangled
, n
);
1820 (*mangled
) += n
+ 1;
1822 if (work
->temp_start
== -1) /* non-recursive call */
1823 work
->temp_start
= declp
->p
- declp
->b
;
1824 string_append (declp
, "<");
1827 string_clear (&arg
);
1831 /* 'T' signals a type parameter */
1833 if (!do_type (work
, mangled
, &arg
))
1834 goto hpacc_template_args_done
;
1839 /* 'U' or 'S' signals an integral value */
1840 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
1841 goto hpacc_template_args_done
;
1845 /* 'A' signals a named constant expression (literal) */
1846 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
1847 goto hpacc_template_args_done
;
1851 /* Today, 1997-09-03, we have only the above types
1852 of template parameters */
1853 /* FIXME: maybe this should fail and return null */
1854 goto hpacc_template_args_done
;
1856 string_appends (declp
, &arg
);
1857 /* Check if we're at the end of template args.
1858 0 if at end of static member of template class,
1859 _ if done with template args for a function */
1860 if ((**mangled
== '\000') || (**mangled
== '_'))
1863 string_append (declp
, ",");
1865 hpacc_template_args_done
:
1866 string_append (declp
, ">");
1867 string_delete (&arg
);
1868 if (**mangled
== '_')
1872 /* ARM template? (Also handles HP cfront extensions) */
1873 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
1878 string_appendn (declp
, *mangled
, p
- *mangled
);
1879 if (work
->temp_start
== -1) /* non-recursive call */
1880 work
->temp_start
= declp
->p
- declp
->b
;
1881 string_append (declp
, "<");
1882 /* should do error checking here */
1884 string_clear (&arg
);
1886 /* Check for type or literal here */
1889 /* HP cfront extensions to ARM for template args */
1890 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1891 /* FIXME: We handle only numeric literals for HP cfront */
1893 /* A typed constant value follows */
1895 if (!do_type (work
, &args
, &type_str
))
1896 goto cfront_template_args_done
;
1897 string_append (&arg
, "(");
1898 string_appends (&arg
, &type_str
);
1899 string_append (&arg
, ")");
1901 goto cfront_template_args_done
;
1903 /* Now snarf a literal value following 'L' */
1904 if (!snarf_numeric_literal (&args
, &arg
))
1905 goto cfront_template_args_done
;
1909 /* Snarf a literal following 'L' */
1911 if (!snarf_numeric_literal (&args
, &arg
))
1912 goto cfront_template_args_done
;
1915 /* Not handling other HP cfront stuff */
1916 if (!do_type (work
, &args
, &arg
))
1917 goto cfront_template_args_done
;
1919 string_appends (declp
, &arg
);
1920 string_append (declp
, ",");
1922 cfront_template_args_done
:
1923 string_delete (&arg
);
1925 --declp
->p
; /* remove extra comma */
1926 string_append (declp
, ">");
1928 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
1929 && (*mangled
)[9] == 'N'
1930 && (*mangled
)[8] == (*mangled
)[10]
1931 && strchr (cplus_markers
, (*mangled
)[8]))
1933 /* A member of the anonymous namespace. */
1934 string_append (declp
, "{anonymous}");
1938 if (work
->temp_start
== -1) /* non-recursive call only */
1939 work
->temp_start
= 0; /* disable in recursive calls */
1940 string_appendn (declp
, *mangled
, n
);
1945 /* Extract a class name, possibly a template with arguments, from the
1946 mangled string; qualifiers, local class indicators, etc. have
1947 already been dealt with */
1950 demangle_class_name (work
, mangled
, declp
)
1951 struct work_stuff
*work
;
1952 const char **mangled
;
1958 n
= consume_count (mangled
);
1961 demangle_arm_hp_template (work
, mangled
, n
, declp
);
1972 demangle_class -- demangle a mangled class sequence
1977 demangle_class (struct work_stuff *work, const char **mangled,
1982 DECLP points to the buffer into which demangling is being done.
1984 *MANGLED points to the current token to be demangled. On input,
1985 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1986 On exit, it points to the next token after the mangled class on
1987 success, or the first unconsumed token on failure.
1989 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1990 we are demangling a constructor or destructor. In this case
1991 we prepend "class::class" or "class::~class" to DECLP.
1993 Otherwise, we prepend "class::" to the current DECLP.
1995 Reset the constructor/destructor flags once they have been
1996 "consumed". This allows demangle_class to be called later during
1997 the same demangling, to do normal class demangling.
1999 Returns 1 if demangling is successful, 0 otherwise.
2004 demangle_class (work
, mangled
, declp
)
2005 struct work_stuff
*work
;
2006 const char **mangled
;
2012 char *save_class_name_end
= 0;
2014 string_init (&class_name
);
2015 btype
= register_Btype (work
);
2016 if (demangle_class_name (work
, mangled
, &class_name
))
2018 save_class_name_end
= class_name
.p
;
2019 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2021 /* adjust so we don't include template args */
2022 if (work
->temp_start
&& (work
->temp_start
!= -1))
2024 class_name
.p
= class_name
.b
+ work
->temp_start
;
2026 string_prepends (declp
, &class_name
);
2027 if (work
-> destructor
& 1)
2029 string_prepend (declp
, "~");
2030 work
-> destructor
-= 1;
2034 work
-> constructor
-= 1;
2037 class_name
.p
= save_class_name_end
;
2038 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2039 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2040 string_prepend (declp
, SCOPE_STRING (work
));
2041 string_prepends (declp
, &class_name
);
2044 string_delete (&class_name
);
2052 demangle_prefix -- consume the mangled name prefix and find signature
2057 demangle_prefix (struct work_stuff *work, const char **mangled,
2062 Consume and demangle the prefix of the mangled name.
2064 DECLP points to the string buffer into which demangled output is
2065 placed. On entry, the buffer is empty. On exit it contains
2066 the root function name, the demangled operator name, or in some
2067 special cases either nothing or the completely demangled result.
2069 MANGLED points to the current pointer into the mangled name. As each
2070 token of the mangled name is consumed, it is updated. Upon entry
2071 the current mangled name pointer points to the first character of
2072 the mangled name. Upon exit, it should point to the first character
2073 of the signature if demangling was successful, or to the first
2074 unconsumed character if demangling of the prefix was unsuccessful.
2076 Returns 1 on success, 0 otherwise.
2080 demangle_prefix (work
, mangled
, declp
)
2081 struct work_stuff
*work
;
2082 const char **mangled
;
2089 if (strlen(*mangled
) > 6
2090 && (strncmp(*mangled
, "_imp__", 6) == 0
2091 || strncmp(*mangled
, "__imp_", 6) == 0))
2093 /* it's a symbol imported from a PE dynamic library. Check for both
2094 new style prefix _imp__ and legacy __imp_ used by older versions
2097 work
->dllimported
= 1;
2099 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2101 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2102 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2104 if ((*mangled
)[9] == 'D')
2106 /* it's a GNU global destructor to be executed at program exit */
2108 work
->destructor
= 2;
2109 if (gnu_special (work
, mangled
, declp
))
2112 else if ((*mangled
)[9] == 'I')
2114 /* it's a GNU global constructor to be executed at program init */
2116 work
->constructor
= 2;
2117 if (gnu_special (work
, mangled
, declp
))
2122 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2124 /* it's a ARM global destructor to be executed at program exit */
2126 work
->destructor
= 2;
2128 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2130 /* it's a ARM global constructor to be executed at program initial */
2132 work
->constructor
= 2;
2135 /* This block of code is a reduction in strength time optimization
2137 scan = mystrstr (*mangled, "__"); */
2143 scan
= strchr (scan
, '_');
2144 } while (scan
!= NULL
&& *++scan
!= '_');
2146 if (scan
!= NULL
) --scan
;
2151 /* We found a sequence of two or more '_', ensure that we start at
2152 the last pair in the sequence. */
2153 i
= strspn (scan
, "_");
2164 else if (work
-> static_type
)
2166 if (!isdigit ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2171 else if ((scan
== *mangled
)
2172 && (isdigit ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2173 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2175 /* The ARM says nothing about the mangling of local variables.
2176 But cfront mangles local variables by prepending __<nesting_level>
2177 to them. As an extension to ARM demangling we handle this case. */
2178 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2179 && isdigit ((unsigned char)scan
[2]))
2181 *mangled
= scan
+ 2;
2182 consume_count (mangled
);
2183 string_append (declp
, *mangled
);
2184 *mangled
+= strlen (*mangled
);
2189 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2190 names like __Q2_3foo3bar for nested type names. So don't accept
2191 this style of constructor for cfront demangling. A GNU
2192 style member-template constructor starts with 'H'. */
2193 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2194 work
-> constructor
+= 1;
2195 *mangled
= scan
+ 2;
2198 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2200 /* Cfront-style parameterized type. Handled later as a signature. */
2204 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2206 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2207 || (scan
[2] == 'p' && scan
[3] == 's')
2208 || (scan
[2] == 'p' && scan
[3] == 't')))
2210 /* EDG-style parameterized type. Handled later as a signature. */
2214 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2216 else if ((scan
== *mangled
) && !isdigit ((unsigned char)scan
[2])
2217 && (scan
[2] != 't'))
2219 /* Mangled name starts with "__". Skip over any leading '_' characters,
2220 then find the next "__" that separates the prefix from the signature.
2222 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2223 || (arm_special (mangled
, declp
) == 0))
2225 while (*scan
== '_')
2229 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2231 /* No separator (I.E. "__not_mangled"), or empty signature
2232 (I.E. "__not_mangled_either__") */
2238 /* Look for the LAST occurrence of __, allowing names to have
2239 the '__' sequence embedded in them.*/
2240 while ((tmp
= mystrstr (scan
+2, "__")) != NULL
)
2242 if (*(scan
+ 2) == '\0')
2245 demangle_function_name (work
, mangled
, declp
, scan
);
2249 else if (*(scan
+ 2) != '\0')
2251 /* Mangled name does not start with "__" but does have one somewhere
2252 in there with non empty stuff after it. Looks like a global
2254 demangle_function_name (work
, mangled
, declp
, scan
);
2258 /* Doesn't look like a mangled name */
2262 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2264 string_append (declp
, *mangled
);
2265 *mangled
+= strlen (*mangled
);
2275 gnu_special -- special handling of gnu mangled strings
2280 gnu_special (struct work_stuff *work, const char **mangled,
2286 Process some special GNU style mangling forms that don't fit
2287 the normal pattern. For example:
2289 _$_3foo (destructor for class foo)
2290 _vt$foo (foo virtual table)
2291 _vt$foo$bar (foo::bar virtual table)
2292 __vt_foo (foo virtual table, new style with thunks)
2293 _3foo$varname (static data member)
2294 _Q22rs2tu$vw (static data member)
2295 __t6vector1Zii (constructor with template)
2296 __thunk_4__$_7ostream (virtual function thunk)
2300 gnu_special (work
, mangled
, declp
)
2301 struct work_stuff
*work
;
2302 const char **mangled
;
2309 if ((*mangled
)[0] == '_'
2310 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2311 && (*mangled
)[2] == '_')
2313 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2315 work
-> destructor
+= 1;
2317 else if ((*mangled
)[0] == '_'
2318 && (((*mangled
)[1] == '_'
2319 && (*mangled
)[2] == 'v'
2320 && (*mangled
)[3] == 't'
2321 && (*mangled
)[4] == '_')
2322 || ((*mangled
)[1] == 'v'
2323 && (*mangled
)[2] == 't'
2324 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2326 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2327 and create the decl. Note that we consume the entire mangled
2328 input string, which means that demangle_signature has no work
2330 if ((*mangled
)[2] == 'v')
2331 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2333 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2334 while (**mangled
!= '\0')
2340 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2343 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2347 if (isdigit((unsigned char)*mangled
[0]))
2349 n
= consume_count(mangled
);
2350 /* We may be seeing a too-large size, or else a
2351 ".<digits>" indicating a static local symbol. In
2352 any case, declare victory and move on; *don't* try
2353 to use n to allocate. */
2354 if (n
> (int) strlen (*mangled
))
2362 n
= strcspn (*mangled
, cplus_markers
);
2364 string_appendn (declp
, *mangled
, n
);
2368 p
= strpbrk (*mangled
, cplus_markers
);
2369 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2373 string_append (declp
, SCOPE_STRING (work
));
2384 string_append (declp
, " virtual table");
2386 else if ((*mangled
)[0] == '_'
2387 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2388 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2390 /* static data member, "_3foo$varname" for example */
2396 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2399 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2402 n
= consume_count (mangled
);
2403 string_appendn (declp
, *mangled
, n
);
2406 if (success
&& (p
== *mangled
))
2408 /* Consumed everything up to the cplus_marker, append the
2411 string_append (declp
, SCOPE_STRING (work
));
2412 n
= strlen (*mangled
);
2413 string_appendn (declp
, *mangled
, n
);
2421 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2423 int delta
= ((*mangled
) += 8, consume_count (mangled
));
2424 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2428 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2429 string_append (declp
, buf
);
2430 string_append (declp
, method
);
2432 n
= strlen (*mangled
);
2440 else if (strncmp (*mangled
, "__t", 3) == 0
2441 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2443 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2449 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2452 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2455 success
= demangle_fund_type (work
, mangled
, declp
);
2458 if (success
&& **mangled
!= '\0')
2461 string_append (declp
, p
);
2471 recursively_demangle(work
, mangled
, result
, namelength
)
2472 struct work_stuff
*work
;
2473 const char **mangled
;
2477 char * recurse
= (char *)NULL
;
2478 char * recurse_dem
= (char *)NULL
;
2480 recurse
= (char *) xmalloc (namelength
+ 1);
2481 memcpy (recurse
, *mangled
, namelength
);
2482 recurse
[namelength
] = '\000';
2484 recurse_dem
= cplus_demangle (recurse
, work
->options
);
2488 string_append (result
, recurse_dem
);
2493 string_appendn (result
, *mangled
, namelength
);
2496 *mangled
+= namelength
;
2503 arm_special -- special handling of ARM/lucid mangled strings
2508 arm_special (const char **mangled,
2514 Process some special ARM style mangling forms that don't fit
2515 the normal pattern. For example:
2517 __vtbl__3foo (foo virtual table)
2518 __vtbl__3foo__3bar (bar::foo virtual table)
2523 arm_special (mangled
, declp
)
2524 const char **mangled
;
2531 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
2533 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2534 and create the decl. Note that we consume the entire mangled
2535 input string, which means that demangle_signature has no work
2537 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
2538 while (*scan
!= '\0') /* first check it can be demangled */
2540 n
= consume_count (&scan
);
2543 return (0); /* no good */
2546 if (scan
[0] == '_' && scan
[1] == '_')
2551 (*mangled
) += ARM_VTABLE_STRLEN
;
2552 while (**mangled
!= '\0')
2554 n
= consume_count (mangled
);
2555 string_prependn (declp
, *mangled
, n
);
2557 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
2559 string_prepend (declp
, "::");
2563 string_append (declp
, " virtual table");
2576 demangle_qualified -- demangle 'Q' qualified name strings
2581 demangle_qualified (struct work_stuff *, const char *mangled,
2582 string *result, int isfuncname, int append);
2586 Demangle a qualified name, such as "Q25Outer5Inner" which is
2587 the mangled form of "Outer::Inner". The demangled output is
2588 prepended or appended to the result string according to the
2589 state of the append flag.
2591 If isfuncname is nonzero, then the qualified name we are building
2592 is going to be used as a member function name, so if it is a
2593 constructor or destructor function, append an appropriate
2594 constructor or destructor name. I.E. for the above example,
2595 the result for use as a constructor is "Outer::Inner::Inner"
2596 and the result for use as a destructor is "Outer::Inner::~Inner".
2600 Numeric conversion is ASCII dependent (FIXME).
2605 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
2606 struct work_stuff
*work
;
2607 const char **mangled
;
2618 int bindex
= register_Btype (work
);
2620 /* We only make use of ISFUNCNAME if the entity is a constructor or
2622 isfuncname
= (isfuncname
2623 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
2625 string_init (&temp
);
2626 string_init (&last_name
);
2628 if ((*mangled
)[0] == 'K')
2630 /* Squangling qualified name reuse */
2633 idx
= consume_count_with_underscores (mangled
);
2634 if (idx
== -1 || idx
>= work
-> numk
)
2637 string_append (&temp
, work
-> ktypevec
[idx
]);
2640 switch ((*mangled
)[1])
2643 /* GNU mangled name with more than 9 classes. The count is preceded
2644 by an underscore (to distinguish it from the <= 9 case) and followed
2645 by an underscore. */
2647 qualifiers
= atoi (p
);
2648 if (!isdigit ((unsigned char)*p
) || *p
== '0')
2651 /* Skip the digits. */
2652 while (isdigit ((unsigned char)*p
))
2670 /* The count is in a single digit. */
2671 num
[0] = (*mangled
)[1];
2673 qualifiers
= atoi (num
);
2675 /* If there is an underscore after the digit, skip it. This is
2676 said to be for ARM-qualified names, but the ARM makes no
2677 mention of such an underscore. Perhaps cfront uses one. */
2678 if ((*mangled
)[2] == '_')
2693 /* Pick off the names and collect them in the temp buffer in the order
2694 in which they are found, separated by '::'. */
2696 while (qualifiers
-- > 0)
2699 string_clear (&last_name
);
2701 if (*mangled
[0] == '_')
2704 if (*mangled
[0] == 't')
2706 /* Here we always append to TEMP since we will want to use
2707 the template name without the template parameters as a
2708 constructor or destructor name. The appropriate
2709 (parameter-less) value is returned by demangle_template
2710 in LAST_NAME. We do not remember the template type here,
2711 in order to match the G++ mangling algorithm. */
2712 success
= demangle_template(work
, mangled
, &temp
,
2717 else if (*mangled
[0] == 'K')
2721 idx
= consume_count_with_underscores (mangled
);
2722 if (idx
== -1 || idx
>= work
->numk
)
2725 string_append (&temp
, work
->ktypevec
[idx
]);
2728 if (!success
) break;
2735 /* Now recursively demangle the qualifier
2736 * This is necessary to deal with templates in
2737 * mangling styles like EDG */
2738 namelength
= consume_count (mangled
);
2739 recursively_demangle(work
, mangled
, &temp
, namelength
);
2743 success
= do_type (work
, mangled
, &last_name
);
2746 string_appends (&temp
, &last_name
);
2751 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
2754 string_append (&temp
, SCOPE_STRING (work
));
2757 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
2759 /* If we are using the result as a function name, we need to append
2760 the appropriate '::' separated constructor or destructor name.
2761 We do this here because this is the most convenient place, where
2762 we already have a pointer to the name and the length of the name. */
2766 string_append (&temp
, SCOPE_STRING (work
));
2767 if (work
-> destructor
& 1)
2768 string_append (&temp
, "~");
2769 string_appends (&temp
, &last_name
);
2772 /* Now either prepend the temp buffer to the result, or append it,
2773 depending upon the state of the append flag. */
2776 string_appends (result
, &temp
);
2779 if (!STRING_EMPTY (result
))
2780 string_append (&temp
, SCOPE_STRING (work
));
2781 string_prepends (result
, &temp
);
2784 string_delete (&last_name
);
2785 string_delete (&temp
);
2793 get_count -- convert an ascii count to integer, consuming tokens
2798 get_count (const char **type, int *count)
2802 Return 0 if no conversion is performed, 1 if a string is converted.
2806 get_count (type
, count
)
2813 if (!isdigit ((unsigned char)**type
))
2819 *count
= **type
- '0';
2821 if (isdigit ((unsigned char)**type
))
2831 while (isdigit ((unsigned char)*p
));
2842 /* RESULT will be initialised here; it will be freed on failure. The
2843 value returned is really a type_kind_t. */
2846 do_type (work
, mangled
, result
)
2847 struct work_stuff
*work
;
2848 const char **mangled
;
2855 const char *remembered_type
;
2858 type_kind_t tk
= tk_none
;
2860 string_init (&btype
);
2861 string_init (&decl
);
2862 string_init (result
);
2866 while (success
&& !done
)
2872 /* A pointer type */
2876 string_prepend (&decl
, "*");
2881 /* A reference type */
2884 string_prepend (&decl
, "&");
2893 if (!STRING_EMPTY (&decl
)
2894 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
2896 string_prepend (&decl
, "(");
2897 string_append (&decl
, ")");
2899 string_append (&decl
, "[");
2900 if (**mangled
!= '_')
2901 success
= demangle_template_value_parm (work
, mangled
, &decl
,
2903 if (**mangled
== '_')
2905 string_append (&decl
, "]");
2909 /* A back reference to a previously seen type */
2912 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
2918 remembered_type
= work
-> typevec
[n
];
2919 mangled
= &remembered_type
;
2926 if (!STRING_EMPTY (&decl
)
2927 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
2929 string_prepend (&decl
, "(");
2930 string_append (&decl
, ")");
2932 /* After picking off the function args, we expect to either find the
2933 function return type (preceded by an '_') or the end of the
2935 if (!demangle_nested_args (work
, mangled
, &decl
)
2936 || (**mangled
!= '_' && **mangled
!= '\0'))
2941 if (success
&& (**mangled
== '_'))
2948 type_quals
= TYPE_UNQUALIFIED
;
2950 member
= **mangled
== 'M';
2952 if (!isdigit ((unsigned char)**mangled
) && **mangled
!= 't')
2958 string_append (&decl
, ")");
2959 string_prepend (&decl
, SCOPE_STRING (work
));
2960 if (isdigit ((unsigned char)**mangled
))
2962 n
= consume_count (mangled
);
2963 if ((int) strlen (*mangled
) < n
)
2968 string_prependn (&decl
, *mangled
, n
);
2974 string_init (&temp
);
2975 success
= demangle_template (work
, mangled
, &temp
,
2979 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
2980 string_clear (&temp
);
2985 string_prepend (&decl
, "(");
2993 type_quals
|= code_for_qualifier (**mangled
);
3001 if (*(*mangled
)++ != 'F')
3007 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3008 || **mangled
!= '_')
3014 if (! PRINT_ANSI_QUALIFIERS
)
3018 if (type_quals
!= TYPE_UNQUALIFIED
)
3020 APPEND_BLANK (&decl
);
3021 string_append (&decl
, qualifier_string (type_quals
));
3032 if (PRINT_ANSI_QUALIFIERS
)
3034 if (!STRING_EMPTY (&decl
))
3035 string_prepend (&decl
, " ");
3037 string_prepend (&decl
, demangle_qualifier (**mangled
));
3052 if (success
) switch (**mangled
)
3054 /* A qualified name, such as "Outer::Inner". */
3058 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3062 /* A back reference to a previously seen squangled type */
3065 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3068 string_append (result
, work
->btypevec
[n
]);
3073 /* A template parm. We substitute the corresponding argument. */
3078 idx
= consume_count_with_underscores (mangled
);
3081 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3082 || consume_count_with_underscores (mangled
) == -1)
3088 if (work
->tmpl_argvec
)
3089 string_append (result
, work
->tmpl_argvec
[idx
]);
3093 sprintf(buf
, "T%d", idx
);
3094 string_append (result
, buf
);
3102 success
= demangle_fund_type (work
, mangled
, result
);
3104 tk
= (type_kind_t
) success
;
3110 if (!STRING_EMPTY (&decl
))
3112 string_append (result
, " ");
3113 string_appends (result
, &decl
);
3117 string_delete (result
);
3118 string_delete (&decl
);
3121 /* Assume an integral type, if we're not sure. */
3122 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3127 /* Given a pointer to a type string that represents a fundamental type
3128 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3129 string in which the demangled output is being built in RESULT, and
3130 the WORK structure, decode the types and add them to the result.
3135 "Sl" => "signed long"
3136 "CUs" => "const unsigned short"
3138 The value returned is really a type_kind_t. */
3141 demangle_fund_type (work
, mangled
, result
)
3142 struct work_stuff
*work
;
3143 const char **mangled
;
3151 type_kind_t tk
= tk_integral
;
3153 string_init (&btype
);
3155 /* First pick off any type qualifiers. There can be more than one. */
3164 if (PRINT_ANSI_QUALIFIERS
)
3166 if (!STRING_EMPTY (result
))
3167 string_prepend (result
, " ");
3168 string_prepend (result
, demangle_qualifier (**mangled
));
3174 APPEND_BLANK (result
);
3175 string_append (result
, "unsigned");
3177 case 'S': /* signed char only */
3179 APPEND_BLANK (result
);
3180 string_append (result
, "signed");
3184 APPEND_BLANK (result
);
3185 string_append (result
, "__complex");
3193 /* Now pick off the fundamental type. There can be only one. */
3202 APPEND_BLANK (result
);
3203 string_append (result
, "void");
3207 APPEND_BLANK (result
);
3208 string_append (result
, "long long");
3212 APPEND_BLANK (result
);
3213 string_append (result
, "long");
3217 APPEND_BLANK (result
);
3218 string_append (result
, "int");
3222 APPEND_BLANK (result
);
3223 string_append (result
, "short");
3227 APPEND_BLANK (result
);
3228 string_append (result
, "bool");
3233 APPEND_BLANK (result
);
3234 string_append (result
, "char");
3239 APPEND_BLANK (result
);
3240 string_append (result
, "wchar_t");
3245 APPEND_BLANK (result
);
3246 string_append (result
, "long double");
3251 APPEND_BLANK (result
);
3252 string_append (result
, "double");
3257 APPEND_BLANK (result
);
3258 string_append (result
, "float");
3263 if (!isdigit ((unsigned char)**mangled
))
3270 if (**mangled
== '_')
3274 for (i
= 0; **mangled
!= '_'; ++(*mangled
), ++i
)
3281 strncpy (buf
, *mangled
, 2);
3284 sscanf (buf
, "%x", &dec
);
3285 sprintf (buf
, "int%i_t", dec
);
3286 APPEND_BLANK (result
);
3287 string_append (result
, buf
);
3291 /* An explicit type, such as "6mytype" or "7integer" */
3303 int bindex
= register_Btype (work
);
3305 string_init (&btype
);
3306 if (demangle_class_name (work
, mangled
, &btype
)) {
3307 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3308 APPEND_BLANK (result
);
3309 string_appends (result
, &btype
);
3313 string_delete (&btype
);
3318 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3319 string_appends (result
, &btype
);
3327 return success
? ((int) tk
) : 0;
3331 /* Handle a template's value parameter for HP aCC (extension from ARM)
3332 **mangled points to 'S' or 'U' */
3335 do_hpacc_template_const_value (work
, mangled
, result
)
3336 struct work_stuff
*work
;
3337 const char **mangled
;
3342 if (**mangled
!= 'U' && **mangled
!= 'S')
3345 unsigned_const
= (**mangled
== 'U');
3352 string_append (result
, "-");
3358 /* special case for -2^31 */
3359 string_append (result
, "-2147483648");
3366 /* We have to be looking at an integer now */
3367 if (!(isdigit ((unsigned char)**mangled
)))
3370 /* We only deal with integral values for template
3371 parameters -- so it's OK to look only for digits */
3372 while (isdigit ((unsigned char)**mangled
))
3374 char_str
[0] = **mangled
;
3375 string_append (result
, char_str
);
3380 string_append (result
, "U");
3382 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3383 with L or LL suffixes. pai/1997-09-03 */
3385 return 1; /* success */
3388 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3389 **mangled is pointing to the 'A' */
3392 do_hpacc_template_literal (work
, mangled
, result
)
3393 struct work_stuff
*work
;
3394 const char **mangled
;
3397 int literal_len
= 0;
3401 if (**mangled
!= 'A')
3406 literal_len
= consume_count (mangled
);
3411 /* Literal parameters are names of arrays, functions, etc. and the
3412 canonical representation uses the address operator */
3413 string_append (result
, "&");
3415 /* Now recursively demangle the literal name */
3416 recurse
= (char *) xmalloc (literal_len
+ 1);
3417 memcpy (recurse
, *mangled
, literal_len
);
3418 recurse
[literal_len
] = '\000';
3420 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3424 string_append (result
, recurse_dem
);
3429 string_appendn (result
, *mangled
, literal_len
);
3431 (*mangled
) += literal_len
;
3438 snarf_numeric_literal (args
, arg
)
3445 string_append (arg
, char_str
);
3448 else if (**args
== '+')
3451 if (!isdigit ((unsigned char)**args
))
3454 while (isdigit ((unsigned char)**args
))
3456 char_str
[0] = **args
;
3457 string_append (arg
, char_str
);
3464 /* Demangle the next argument, given by MANGLED into RESULT, which
3465 *should be an uninitialized* string. It will be initialized here,
3466 and free'd should anything go wrong. */
3469 do_arg (work
, mangled
, result
)
3470 struct work_stuff
*work
;
3471 const char **mangled
;
3474 /* Remember where we started so that we can record the type, for
3475 non-squangling type remembering. */
3476 const char *start
= *mangled
;
3478 string_init (result
);
3480 if (work
->nrepeats
> 0)
3484 if (work
->previous_argument
== 0)
3487 /* We want to reissue the previous type in this argument list. */
3488 string_appends (result
, work
->previous_argument
);
3492 if (**mangled
== 'n')
3494 /* A squangling-style repeat. */
3496 work
->nrepeats
= consume_count(mangled
);
3498 if (work
->nrepeats
== 0)
3499 /* This was not a repeat count after all. */
3502 if (work
->nrepeats
> 9)
3504 if (**mangled
!= '_')
3505 /* The repeat count should be followed by an '_' in this
3512 /* Now, the repeat is all set up. */
3513 return do_arg (work
, mangled
, result
);
3516 /* Save the result in WORK->previous_argument so that we can find it
3517 if it's repeated. Note that saving START is not good enough: we
3518 do not want to add additional types to the back-referenceable
3519 type vector when processing a repeated type. */
3520 if (work
->previous_argument
)
3521 string_clear (work
->previous_argument
);
3524 work
->previous_argument
= (string
*) xmalloc (sizeof (string
));
3525 string_init (work
->previous_argument
);
3528 if (!do_type (work
, mangled
, work
->previous_argument
))
3531 string_appends (result
, work
->previous_argument
);
3533 remember_type (work
, start
, *mangled
- start
);
3538 remember_type (work
, start
, len
)
3539 struct work_stuff
*work
;
3545 if (work
->forgetting_types
)
3548 if (work
-> ntypes
>= work
-> typevec_size
)
3550 if (work
-> typevec_size
== 0)
3552 work
-> typevec_size
= 3;
3554 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
3558 work
-> typevec_size
*= 2;
3560 = (char **) xrealloc ((char *)work
-> typevec
,
3561 sizeof (char *) * work
-> typevec_size
);
3564 tem
= xmalloc (len
+ 1);
3565 memcpy (tem
, start
, len
);
3567 work
-> typevec
[work
-> ntypes
++] = tem
;
3571 /* Remember a K type class qualifier. */
3573 remember_Ktype (work
, start
, len
)
3574 struct work_stuff
*work
;
3580 if (work
-> numk
>= work
-> ksize
)
3582 if (work
-> ksize
== 0)
3586 = (char **) xmalloc (sizeof (char *) * work
-> ksize
);
3592 = (char **) xrealloc ((char *)work
-> ktypevec
,
3593 sizeof (char *) * work
-> ksize
);
3596 tem
= xmalloc (len
+ 1);
3597 memcpy (tem
, start
, len
);
3599 work
-> ktypevec
[work
-> numk
++] = tem
;
3602 /* Register a B code, and get an index for it. B codes are registered
3603 as they are seen, rather than as they are completed, so map<temp<char> >
3604 registers map<temp<char> > as B0, and temp<char> as B1 */
3607 register_Btype (work
)
3608 struct work_stuff
*work
;
3612 if (work
-> numb
>= work
-> bsize
)
3614 if (work
-> bsize
== 0)
3618 = (char **) xmalloc (sizeof (char *) * work
-> bsize
);
3624 = (char **) xrealloc ((char *)work
-> btypevec
,
3625 sizeof (char *) * work
-> bsize
);
3628 ret
= work
-> numb
++;
3629 work
-> btypevec
[ret
] = NULL
;
3633 /* Store a value into a previously registered B code type. */
3636 remember_Btype (work
, start
, len
, index
)
3637 struct work_stuff
*work
;
3643 tem
= xmalloc (len
+ 1);
3644 memcpy (tem
, start
, len
);
3646 work
-> btypevec
[index
] = tem
;
3649 /* Lose all the info related to B and K type codes. */
3651 forget_B_and_K_types (work
)
3652 struct work_stuff
*work
;
3656 while (work
-> numk
> 0)
3658 i
= --(work
-> numk
);
3659 if (work
-> ktypevec
[i
] != NULL
)
3661 free (work
-> ktypevec
[i
]);
3662 work
-> ktypevec
[i
] = NULL
;
3666 while (work
-> numb
> 0)
3668 i
= --(work
-> numb
);
3669 if (work
-> btypevec
[i
] != NULL
)
3671 free (work
-> btypevec
[i
]);
3672 work
-> btypevec
[i
] = NULL
;
3676 /* Forget the remembered types, but not the type vector itself. */
3680 struct work_stuff
*work
;
3684 while (work
-> ntypes
> 0)
3686 i
= --(work
-> ntypes
);
3687 if (work
-> typevec
[i
] != NULL
)
3689 free (work
-> typevec
[i
]);
3690 work
-> typevec
[i
] = NULL
;
3695 /* Process the argument list part of the signature, after any class spec
3696 has been consumed, as well as the first 'F' character (if any). For
3699 "__als__3fooRT0" => process "RT0"
3700 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3702 DECLP must be already initialised, usually non-empty. It won't be freed
3705 Note that g++ differs significantly from ARM and lucid style mangling
3706 with regards to references to previously seen types. For example, given
3707 the source fragment:
3711 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3714 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3715 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3717 g++ produces the names:
3722 while lcc (and presumably other ARM style compilers as well) produces:
3724 foo__FiR3fooT1T2T1T2
3725 __ct__3fooFiR3fooT1T2T1T2
3727 Note that g++ bases its type numbers starting at zero and counts all
3728 previously seen types, while lucid/ARM bases its type numbers starting
3729 at one and only considers types after it has seen the 'F' character
3730 indicating the start of the function args. For lucid/ARM style, we
3731 account for this difference by discarding any previously seen types when
3732 we see the 'F' character, and subtracting one from the type number
3738 demangle_args (work
, mangled
, declp
)
3739 struct work_stuff
*work
;
3740 const char **mangled
;
3750 if (PRINT_ARG_TYPES
)
3752 string_append (declp
, "(");
3753 if (**mangled
== '\0')
3755 string_append (declp
, "void");
3759 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
3760 || work
->nrepeats
> 0)
3762 if ((**mangled
== 'N') || (**mangled
== 'T'))
3764 temptype
= *(*mangled
)++;
3766 if (temptype
== 'N')
3768 if (!get_count (mangled
, &r
))
3777 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
3779 /* If we have 10 or more types we might have more than a 1 digit
3780 index so we'll have to consume the whole count here. This
3781 will lose if the next thing is a type name preceded by a
3782 count but it's impossible to demangle that case properly
3783 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3784 Pc, ...)" or "(..., type12, char *, ...)" */
3785 if ((t
= consume_count(mangled
)) == 0)
3792 if (!get_count (mangled
, &t
))
3797 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
3801 /* Validate the type index. Protect against illegal indices from
3802 malformed type strings. */
3803 if ((t
< 0) || (t
>= work
-> ntypes
))
3807 while (work
->nrepeats
> 0 || --r
>= 0)
3809 tem
= work
-> typevec
[t
];
3810 if (need_comma
&& PRINT_ARG_TYPES
)
3812 string_append (declp
, ", ");
3814 if (!do_arg (work
, &tem
, &arg
))
3818 if (PRINT_ARG_TYPES
)
3820 string_appends (declp
, &arg
);
3822 string_delete (&arg
);
3828 if (need_comma
&& PRINT_ARG_TYPES
)
3829 string_append (declp
, ", ");
3830 if (!do_arg (work
, mangled
, &arg
))
3832 if (PRINT_ARG_TYPES
)
3833 string_appends (declp
, &arg
);
3834 string_delete (&arg
);
3839 if (**mangled
== 'e')
3842 if (PRINT_ARG_TYPES
)
3846 string_append (declp
, ",");
3848 string_append (declp
, "...");
3852 if (PRINT_ARG_TYPES
)
3854 string_append (declp
, ")");
3859 /* Like demangle_args, but for demangling the argument lists of function
3860 and method pointers or references, not top-level declarations. */
3863 demangle_nested_args (work
, mangled
, declp
)
3864 struct work_stuff
*work
;
3865 const char **mangled
;
3868 string
* saved_previous_argument
;
3872 /* The G++ name-mangling algorithm does not remember types on nested
3873 argument lists, unless -fsquangling is used, and in that case the
3874 type vector updated by remember_type is not used. So, we turn
3875 off remembering of types here. */
3876 ++work
->forgetting_types
;
3878 /* For the repeat codes used with -fsquangling, we must keep track of
3879 the last argument. */
3880 saved_previous_argument
= work
->previous_argument
;
3881 saved_nrepeats
= work
->nrepeats
;
3882 work
->previous_argument
= 0;
3885 /* Actually demangle the arguments. */
3886 result
= demangle_args (work
, mangled
, declp
);
3888 /* Restore the previous_argument field. */
3889 if (work
->previous_argument
)
3890 string_delete (work
->previous_argument
);
3891 work
->previous_argument
= saved_previous_argument
;
3892 work
->nrepeats
= saved_nrepeats
;
3898 demangle_function_name (work
, mangled
, declp
, scan
)
3899 struct work_stuff
*work
;
3900 const char **mangled
;
3908 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
3909 string_need (declp
, 1);
3910 *(declp
-> p
) = '\0';
3912 /* Consume the function name, including the "__" separating the name
3913 from the signature. We are guaranteed that SCAN points to the
3916 (*mangled
) = scan
+ 2;
3917 /* We may be looking at an instantiation of a template function:
3918 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
3919 following _F marks the start of the function arguments. Handle
3920 the template arguments first. */
3922 if (HP_DEMANGLING
&& (**mangled
== 'X'))
3924 demangle_arm_hp_template (work
, mangled
, 0, declp
);
3925 /* This leaves MANGLED pointing to the 'F' marking func args */
3928 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
3931 /* See if we have an ARM style constructor or destructor operator.
3932 If so, then just record it, clear the decl, and return.
3933 We can't build the actual constructor/destructor decl until later,
3934 when we recover the class name from the signature. */
3936 if (strcmp (declp
-> b
, "__ct") == 0)
3938 work
-> constructor
+= 1;
3939 string_clear (declp
);
3942 else if (strcmp (declp
-> b
, "__dt") == 0)
3944 work
-> destructor
+= 1;
3945 string_clear (declp
);
3950 if (declp
->p
- declp
->b
>= 3
3951 && declp
->b
[0] == 'o'
3952 && declp
->b
[1] == 'p'
3953 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
3955 /* see if it's an assignment expression */
3956 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
3957 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
3959 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
3961 int len
= declp
->p
- declp
->b
- 10;
3962 if ((int) strlen (optable
[i
].in
) == len
3963 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
3965 string_clear (declp
);
3966 string_append (declp
, "operator");
3967 string_append (declp
, optable
[i
].out
);
3968 string_append (declp
, "=");
3975 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
3977 int len
= declp
->p
- declp
->b
- 3;
3978 if ((int) strlen (optable
[i
].in
) == len
3979 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
3981 string_clear (declp
);
3982 string_append (declp
, "operator");
3983 string_append (declp
, optable
[i
].out
);
3989 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
3990 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
3992 /* type conversion operator */
3994 if (do_type (work
, &tem
, &type
))
3996 string_clear (declp
);
3997 string_append (declp
, "operator ");
3998 string_appends (declp
, &type
);
3999 string_delete (&type
);
4002 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4003 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4006 /* type conversion operator. */
4008 if (do_type (work
, &tem
, &type
))
4010 string_clear (declp
);
4011 string_append (declp
, "operator ");
4012 string_appends (declp
, &type
);
4013 string_delete (&type
);
4016 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4017 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
4018 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
4020 if (declp
->b
[4] == '\0')
4023 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4025 if (strlen (optable
[i
].in
) == 2
4026 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4028 string_clear (declp
);
4029 string_append (declp
, "operator");
4030 string_append (declp
, optable
[i
].out
);
4037 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4040 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4042 if (strlen (optable
[i
].in
) == 3
4043 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4045 string_clear (declp
);
4046 string_append (declp
, "operator");
4047 string_append (declp
, optable
[i
].out
);
4056 /* a mini string-handling package */
4071 s
->p
= s
->b
= xmalloc (n
);
4074 else if (s
->e
- s
->p
< n
)
4079 s
->b
= xrealloc (s
->b
, n
);
4092 s
->b
= s
->e
= s
->p
= NULL
;
4100 s
->b
= s
->p
= s
->e
= NULL
;
4116 return (s
->b
== s
->p
);
4122 string_append (p
, s
)
4127 if (s
== NULL
|| *s
== '\0')
4131 memcpy (p
->p
, s
, n
);
4136 string_appends (p
, s
)
4145 memcpy (p
->p
, s
->b
, n
);
4151 string_appendn (p
, s
, n
)
4159 memcpy (p
->p
, s
, n
);
4165 string_prepend (p
, s
)
4169 if (s
!= NULL
&& *s
!= '\0')
4171 string_prependn (p
, s
, strlen (s
));
4176 string_prepends (p
, s
)
4181 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4186 string_prependn (p
, s
, n
)
4196 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4200 memcpy (p
->b
, s
, n
);
4205 /* To generate a standalone demangler program for testing purposes,
4206 just compile and link this file with -DMAIN and libiberty.a. When
4207 run, it demangles each command line arg, or each stdin string, and
4208 prints the result on stdout. */
4214 static char *program_name
;
4215 static char *program_version
= VERSION
;
4216 static int flags
= DMGL_PARAMS
| DMGL_ANSI
;
4218 static void demangle_it
PARAMS ((char *));
4219 static void usage
PARAMS ((FILE *, int));
4220 static void fatal
PARAMS ((char *));
4223 demangle_it (mangled_name
)
4228 result
= cplus_demangle (mangled_name
, flags
);
4231 printf ("%s\n", mangled_name
);
4235 printf ("%s\n", result
);
4241 usage (stream
, status
)
4246 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4247 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4248 [--help] [--version] [arg...]\n",
4253 #define MBUF_SIZE 32767
4254 char mbuffer
[MBUF_SIZE
];
4256 /* Defined in the automatically-generated underscore.c. */
4257 extern int prepends_underscore
;
4259 int strip_underscore
= 0;
4261 static struct option long_options
[] = {
4262 {"strip-underscores", no_argument
, 0, '_'},
4263 {"format", required_argument
, 0, 's'},
4264 {"help", no_argument
, 0, 'h'},
4265 {"no-strip-underscores", no_argument
, 0, 'n'},
4266 {"version", no_argument
, 0, 'v'},
4267 {0, no_argument
, 0, 0}
4270 /* More 'friendly' abort that prints the line and file.
4271 config.h can #define abort fancy_abort if you like that sort of thing. */
4276 fatal ("Internal gcc abort.");
4287 program_name
= argv
[0];
4289 strip_underscore
= prepends_underscore
;
4291 while ((c
= getopt_long (argc
, argv
, "_ns:j", long_options
, (int *) 0)) != EOF
)
4301 strip_underscore
= 0;
4304 printf ("GNU %s (C++ demangler), version %s\n", program_name
, program_version
);
4307 strip_underscore
= 1;
4310 if (strcmp (optarg
, "gnu") == 0)
4312 current_demangling_style
= gnu_demangling
;
4314 else if (strcmp (optarg
, "lucid") == 0)
4316 current_demangling_style
= lucid_demangling
;
4318 else if (strcmp (optarg
, "arm") == 0)
4320 current_demangling_style
= arm_demangling
;
4322 else if (strcmp (optarg
, "hp") == 0)
4324 current_demangling_style
= hp_demangling
;
4326 else if (strcmp (optarg
, "edg") == 0)
4328 current_demangling_style
= edg_demangling
;
4332 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
4333 program_name
, optarg
);
4342 for ( ; optind
< argc
; optind
++)
4344 demangle_it (argv
[optind
]);
4353 /* Try to read a label. */
4354 while (c
!= EOF
&& (isalnum(c
) || c
== '_' || c
== '$' || c
== '.' ||
4355 c
== '<' || c
== '>' || c
== '#' || c
== ',' || c
== '*' || c
== '&' ||
4356 c
== '[' || c
== ']' || c
== ':' || c
== '(' || c
== ')'))
4357 /* the ones in the 2nd & 3rd lines were added to handle
4358 HP aCC template specialization manglings */
4360 if (i
>= MBUF_SIZE
-1)
4369 if (mbuffer
[0] == '.')
4371 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
4379 result
= cplus_demangle (mbuffer
+ skip_first
, flags
);
4382 if (mbuffer
[0] == '.')
4384 fputs (result
, stdout
);
4388 fputs (mbuffer
, stdout
);
4405 fprintf (stderr
, "%s: %s\n", program_name
, str
);
4413 register PTR value
= (PTR
) malloc (size
);
4415 fatal ("virtual memory exhausted");
4420 xrealloc (ptr
, size
)
4424 register PTR value
= (PTR
) realloc (ptr
, size
);
4426 fatal ("virtual memory exhausted");