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
6 This file is part of the libiberty library.
7 Libiberty is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 Libiberty is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with libiberty; see the file COPYING.LIB. If
19 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
24 This file imports xmalloc and xrealloc, which are like malloc and
25 realloc except that they generate a fatal error if there is no
28 /* This file lives in both GCC and libiberty. When making changes, please
29 try not to break either. */
36 #include <sys/types.h>
48 #undef CURRENT_DEMANGLING_STYLE
49 #define CURRENT_DEMANGLING_STYLE work->options
51 extern char *xmalloc
PARAMS((unsigned));
52 extern char *xrealloc
PARAMS((char *, unsigned));
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' };
98 set_cplus_marker_for_demangling (ch
)
101 cplus_markers
[0] = ch
;
104 typedef struct string
/* Beware: these aren't required to be */
105 { /* '\0' terminated. */
106 char *b
; /* pointer to start of string */
107 char *p
; /* pointer after last character */
108 char *e
; /* pointer after end of allocated space */
111 /* Stuff that is shared between sub-routines.
112 Using a shared structure allows cplus_demangle to be reentrant. */
128 int static_type
; /* A static member function */
129 int const_type
; /* A const member function */
130 int volatile_type
; /* A volatile member function */
131 int dllimported
; /* Symbol imported from a PE DLL */
132 char **tmpl_argvec
; /* Template function arguments. */
133 int ntmpl_args
; /* The number of template function arguments. */
134 int forgetting_types
; /* Nonzero if we are not remembering the types
136 string
* previous_argument
; /* The last function argument demangled. */
137 int nrepeats
; /* The number of times to repeat the previous
141 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
142 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
144 static const struct optable
150 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
151 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
152 {"new", " new", 0}, /* old (1.91, and 1.x) */
153 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
154 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
155 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
156 {"as", "=", DMGL_ANSI
}, /* ansi */
157 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
158 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
159 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
160 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
161 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
162 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
163 {"plus", "+", 0}, /* old */
164 {"pl", "+", DMGL_ANSI
}, /* ansi */
165 {"apl", "+=", DMGL_ANSI
}, /* ansi */
166 {"minus", "-", 0}, /* old */
167 {"mi", "-", DMGL_ANSI
}, /* ansi */
168 {"ami", "-=", DMGL_ANSI
}, /* ansi */
169 {"mult", "*", 0}, /* old */
170 {"ml", "*", DMGL_ANSI
}, /* ansi */
171 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
172 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
173 {"convert", "+", 0}, /* old (unary +) */
174 {"negate", "-", 0}, /* old (unary -) */
175 {"trunc_mod", "%", 0}, /* old */
176 {"md", "%", DMGL_ANSI
}, /* ansi */
177 {"amd", "%=", DMGL_ANSI
}, /* ansi */
178 {"trunc_div", "/", 0}, /* old */
179 {"dv", "/", DMGL_ANSI
}, /* ansi */
180 {"adv", "/=", DMGL_ANSI
}, /* ansi */
181 {"truth_andif", "&&", 0}, /* old */
182 {"aa", "&&", DMGL_ANSI
}, /* ansi */
183 {"truth_orif", "||", 0}, /* old */
184 {"oo", "||", DMGL_ANSI
}, /* ansi */
185 {"truth_not", "!", 0}, /* old */
186 {"nt", "!", DMGL_ANSI
}, /* ansi */
187 {"postincrement","++", 0}, /* old */
188 {"pp", "++", DMGL_ANSI
}, /* ansi */
189 {"postdecrement","--", 0}, /* old */
190 {"mm", "--", DMGL_ANSI
}, /* ansi */
191 {"bit_ior", "|", 0}, /* old */
192 {"or", "|", DMGL_ANSI
}, /* ansi */
193 {"aor", "|=", DMGL_ANSI
}, /* ansi */
194 {"bit_xor", "^", 0}, /* old */
195 {"er", "^", DMGL_ANSI
}, /* ansi */
196 {"aer", "^=", DMGL_ANSI
}, /* ansi */
197 {"bit_and", "&", 0}, /* old */
198 {"ad", "&", DMGL_ANSI
}, /* ansi */
199 {"aad", "&=", DMGL_ANSI
}, /* ansi */
200 {"bit_not", "~", 0}, /* old */
201 {"co", "~", DMGL_ANSI
}, /* ansi */
202 {"call", "()", 0}, /* old */
203 {"cl", "()", DMGL_ANSI
}, /* ansi */
204 {"alshift", "<<", 0}, /* old */
205 {"ls", "<<", DMGL_ANSI
}, /* ansi */
206 {"als", "<<=", DMGL_ANSI
}, /* ansi */
207 {"arshift", ">>", 0}, /* old */
208 {"rs", ">>", DMGL_ANSI
}, /* ansi */
209 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
210 {"component", "->", 0}, /* old */
211 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
212 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
213 {"indirect", "*", 0}, /* old */
214 {"method_call", "->()", 0}, /* old */
215 {"addr", "&", 0}, /* old (unary &) */
216 {"array", "[]", 0}, /* old */
217 {"vc", "[]", DMGL_ANSI
}, /* ansi */
218 {"compound", ", ", 0}, /* old */
219 {"cm", ", ", DMGL_ANSI
}, /* ansi */
220 {"cond", "?:", 0}, /* old */
221 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
222 {"max", ">?", 0}, /* old */
223 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
224 {"min", "<?", 0}, /* old */
225 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
226 {"nop", "", 0}, /* old (for operator=) */
227 {"rm", "->*", DMGL_ANSI
}, /* ansi */
228 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
231 /* These values are used to indicate the various type varieties.
232 They are all non-zero so that they can be used as `success'
234 typedef enum type_kind_t
244 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
245 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
246 string_prepend(str, " ");}
247 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
248 string_append(str, " ");}
249 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
251 /* The scope separator appropriate for the language being demangled. */
252 #define SCOPE_STRING(work) "::"
254 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
255 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
257 /* Prototypes for local functions */
260 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
263 squangle_mop_up
PARAMS ((struct work_stuff
*));
267 demangle_method_args
PARAMS ((struct work_stuff
*, const char **, string
*));
271 internal_cplus_demangle
PARAMS ((struct work_stuff
*, const char *));
274 demangle_template_template_parm
PARAMS ((struct work_stuff
*work
,
275 const char **, string
*));
278 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*,
279 string
*, int, int));
282 arm_pt
PARAMS ((struct work_stuff
*, const char *, int, const char **,
286 demangle_arm_pt
PARAMS ((struct work_stuff
*, const char **, int, string
*));
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
));
395 /* Translate count to integer, consuming tokens in the process.
396 Conversion terminates on the first non-digit character.
397 Trying to consume something that isn't a count results in
398 no consumption of input and a return of 0. */
406 while (isdigit ((unsigned char)**type
))
409 count
+= **type
- '0';
416 /* Like consume_count, but for counts that are preceded and followed
417 by '_' if they are greater than 10. Also, -1 is returned for
418 failure, since 0 can be a valid value. */
421 consume_count_with_underscores (mangled
)
422 const char **mangled
;
426 if (**mangled
== '_')
429 if (!isdigit ((unsigned char)**mangled
))
432 idx
= consume_count (mangled
);
433 if (**mangled
!= '_')
434 /* The trailing underscore was missing. */
441 if (**mangled
< '0' || **mangled
> '9')
444 idx
= **mangled
- '0';
452 cplus_demangle_opname (opname
, result
, options
)
459 struct work_stuff work
[1];
462 len
= strlen(opname
);
465 memset ((char *) work
, 0, sizeof (work
));
466 work
->options
= options
;
468 if (opname
[0] == '_' && opname
[1] == '_'
469 && opname
[2] == 'o' && opname
[3] == 'p')
472 /* type conversion operator. */
474 if (do_type (work
, &tem
, &type
))
476 strcat (result
, "operator ");
477 strncat (result
, type
.b
, type
.p
- type
.b
);
478 string_delete (&type
);
482 else if (opname
[0] == '_' && opname
[1] == '_'
483 && opname
[2] >= 'a' && opname
[2] <= 'z'
484 && opname
[3] >= 'a' && opname
[3] <= 'z')
486 if (opname
[4] == '\0')
490 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
492 if (strlen (optable
[i
].in
) == 2
493 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
495 strcat (result
, "operator");
496 strcat (result
, optable
[i
].out
);
504 if (opname
[2] == 'a' && opname
[5] == '\0')
508 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
510 if (strlen (optable
[i
].in
) == 3
511 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
513 strcat (result
, "operator");
514 strcat (result
, optable
[i
].out
);
525 && strchr (cplus_markers
, opname
[2]) != NULL
)
527 /* see if it's an assignment expression */
528 if (len
>= 10 /* op$assign_ */
529 && memcmp (opname
+ 3, "assign_", 7) == 0)
532 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
535 if ((int) strlen (optable
[i
].in
) == len1
536 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
538 strcat (result
, "operator");
539 strcat (result
, optable
[i
].out
);
540 strcat (result
, "=");
549 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
552 if ((int) strlen (optable
[i
].in
) == len1
553 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
555 strcat (result
, "operator");
556 strcat (result
, optable
[i
].out
);
563 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
564 && strchr (cplus_markers
, opname
[4]) != NULL
)
566 /* type conversion operator */
568 if (do_type (work
, &tem
, &type
))
570 strcat (result
, "operator ");
571 strncat (result
, type
.b
, type
.p
- type
.b
);
572 string_delete (&type
);
576 squangle_mop_up (work
);
580 /* Takes operator name as e.g. "++" and returns mangled
581 operator name (e.g. "postincrement_expr"), or NULL if not found.
583 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
584 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
587 cplus_mangle_opname (opname
, options
)
594 len
= strlen (opname
);
595 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
597 if ((int) strlen (optable
[i
].out
) == len
598 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
599 && memcmp (optable
[i
].out
, opname
, len
) == 0)
600 return optable
[i
].in
;
605 /* char *cplus_demangle (const char *mangled, int options)
607 If MANGLED is a mangled function name produced by GNU C++, then
608 a pointer to a malloced string giving a C++ representation
609 of the name will be returned; otherwise NULL will be returned.
610 It is the caller's responsibility to free the string which
613 The OPTIONS arg may contain one or more of the following bits:
615 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
617 DMGL_PARAMS Function parameters are included.
621 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
622 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
623 cplus_demangle ("foo__1Ai", 0) => "A::foo"
625 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
626 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
627 cplus_demangle ("foo__1Afe", 0) => "A::foo"
629 Note that any leading underscores, or other such characters prepended by
630 the compilation system, are presumed to have already been stripped from
634 cplus_demangle (mangled
, options
)
639 struct work_stuff work
[1];
640 memset ((char *) work
, 0, sizeof (work
));
641 work
-> options
= options
;
642 if ((work
-> options
& DMGL_STYLE_MASK
) == 0)
643 work
-> options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
645 ret
= internal_cplus_demangle (work
, mangled
);
646 squangle_mop_up (work
);
651 /* This function performs most of what cplus_demangle use to do, but
652 to be able to demangle a name with a B, K or n code, we need to
653 have a longer term memory of what types have been seen. The original
654 now intializes and cleans up the squangle code info, while internal
655 calls go directly to this routine to avoid resetting that info. */
658 internal_cplus_demangle (work
, mangled
)
659 struct work_stuff
*work
;
665 char *demangled
= NULL
;
667 int saved_volatile_type
;
668 s1
= work
->constructor
;
669 s2
= work
->destructor
;
670 s3
= work
->static_type
;
671 s4
= work
->const_type
;
672 saved_volatile_type
= work
->volatile_type
;
673 work
->constructor
= work
->destructor
= 0;
674 work
->static_type
= work
->const_type
= 0;
675 work
->volatile_type
= 0;
676 work
->dllimported
= 0;
678 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
682 /* First check to see if gnu style demangling is active and if the
683 string to be demangled contains a CPLUS_MARKER. If so, attempt to
684 recognize one of the gnu special forms rather than looking for a
685 standard prefix. In particular, don't worry about whether there
686 is a "__" string in the mangled string. Consider "_$_5__foo" for
689 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
691 success
= gnu_special (work
, &mangled
, &decl
);
695 success
= demangle_prefix (work
, &mangled
, &decl
);
697 if (success
&& (*mangled
!= '\0'))
699 success
= demangle_signature (work
, &mangled
, &decl
);
701 if (work
->constructor
== 2)
703 string_prepend (&decl
, "global constructors keyed to ");
704 work
->constructor
= 0;
706 else if (work
->destructor
== 2)
708 string_prepend (&decl
, "global destructors keyed to ");
709 work
->destructor
= 0;
711 else if (work
->dllimported
== 1)
713 string_prepend (&decl
, "import stub for ");
714 work
->dllimported
= 0;
716 demangled
= mop_up (work
, &decl
, success
);
718 work
->constructor
= s1
;
719 work
->destructor
= s2
;
720 work
->static_type
= s3
;
721 work
->const_type
= s4
;
722 work
->volatile_type
= saved_volatile_type
;
727 /* Clear out and squangling related storage */
729 squangle_mop_up (work
)
730 struct work_stuff
*work
;
732 /* clean up the B and K type mangling types. */
733 forget_B_and_K_types (work
);
734 if (work
-> btypevec
!= NULL
)
736 free ((char *) work
-> btypevec
);
738 if (work
-> ktypevec
!= NULL
)
740 free ((char *) work
-> ktypevec
);
744 /* Clear out any mangled storage */
747 mop_up (work
, declp
, success
)
748 struct work_stuff
*work
;
752 char *demangled
= NULL
;
754 /* Discard the remembered types, if any. */
757 if (work
-> typevec
!= NULL
)
759 free ((char *) work
-> typevec
);
760 work
-> typevec
= NULL
;
762 if (work
->tmpl_argvec
)
766 for (i
= 0; i
< work
->ntmpl_args
; i
++)
767 if (work
->tmpl_argvec
[i
])
768 free ((char*) work
->tmpl_argvec
[i
]);
770 free ((char*) work
->tmpl_argvec
);
771 work
->tmpl_argvec
= NULL
;
773 if (work
->previous_argument
)
775 string_delete (work
->previous_argument
);
776 free ((char*) work
->previous_argument
);
779 /* If demangling was successful, ensure that the demangled string is null
780 terminated and return it. Otherwise, free the demangling decl. */
784 string_delete (declp
);
788 string_appendn (declp
, "", 1);
789 demangled
= declp
-> b
;
798 demangle_signature -- demangle the signature part of a mangled name
803 demangle_signature (struct work_stuff *work, const char **mangled,
808 Consume and demangle the signature portion of the mangled name.
810 DECLP is the string where demangled output is being built. At
811 entry it contains the demangled root name from the mangled name
812 prefix. I.E. either a demangled operator name or the root function
813 name. In some special cases, it may contain nothing.
815 *MANGLED points to the current unconsumed location in the mangled
816 name. As tokens are consumed and demangling is performed, the
817 pointer is updated to continuously point at the next token to
820 Demangling GNU style mangled names is nasty because there is no
821 explicit token that marks the start of the outermost function
825 demangle_signature (work
, mangled
, declp
)
826 struct work_stuff
*work
;
827 const char **mangled
;
833 int expect_return_type
= 0;
834 const char *oldmangled
= NULL
;
838 while (success
&& (**mangled
!= '\0'))
843 oldmangled
= *mangled
;
844 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
846 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
847 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
853 oldmangled
= *mangled
;
854 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
855 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
863 /* Static member function */
864 if (oldmangled
== NULL
)
866 oldmangled
= *mangled
;
869 work
-> static_type
= 1;
874 if (**mangled
== 'C')
875 work
-> const_type
= 1;
877 work
->volatile_type
= 1;
879 /* a qualified member function */
880 if (oldmangled
== NULL
)
881 oldmangled
= *mangled
;
885 case '0': case '1': case '2': case '3': case '4':
886 case '5': case '6': case '7': case '8': case '9':
887 if (oldmangled
== NULL
)
889 oldmangled
= *mangled
;
891 success
= demangle_class (work
, mangled
, declp
);
894 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
896 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
906 success
= do_type (work
, mangled
, &s
);
909 string_append (&s
, SCOPE_STRING (work
));
910 string_prepends (declp
, &s
);
919 /* ARM style demangling includes a specific 'F' character after
920 the class name. For GNU style, it is just implied. So we can
921 safely just consume any 'F' at this point and be compatible
922 with either style. */
928 /* For lucid/ARM style we have to forget any types we might
929 have remembered up to this point, since they were not argument
930 types. GNU style considers all types seen as available for
931 back references. See comment in demangle_args() */
933 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
)
937 success
= demangle_args (work
, mangled
, declp
);
942 string_init(&trawname
);
944 if (oldmangled
== NULL
)
946 oldmangled
= *mangled
;
948 success
= demangle_template (work
, mangled
, &tname
,
952 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
954 string_append (&tname
, SCOPE_STRING (work
));
956 string_prepends(declp
, &tname
);
957 if (work
-> destructor
& 1)
959 string_prepend (&trawname
, "~");
960 string_appends (declp
, &trawname
);
961 work
->destructor
-= 1;
963 if ((work
->constructor
& 1) || (work
->destructor
& 1))
965 string_appends (declp
, &trawname
);
966 work
->constructor
-= 1;
968 string_delete(&trawname
);
969 string_delete(&tname
);
975 if (GNU_DEMANGLING
&& expect_return_type
)
977 /* Read the return type. */
979 string_init (&return_type
);
982 success
= do_type (work
, mangled
, &return_type
);
983 APPEND_BLANK (&return_type
);
985 string_prepends (declp
, &return_type
);
986 string_delete (&return_type
);
990 /* At the outermost level, we cannot have a return type specified,
991 so if we run into another '_' at this point we are dealing with
992 a mangled name that is either bogus, or has been mangled by
993 some algorithm we don't know how to deal with. So just
994 reject the entire demangling. */
1001 /* A G++ template function. Read the template arguments. */
1002 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1004 if (!(work
->constructor
& 1))
1005 expect_return_type
= 1;
1014 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1016 /* Assume we have stumbled onto the first outermost function
1017 argument token, and start processing args. */
1019 success
= demangle_args (work
, mangled
, declp
);
1023 /* Non-GNU demanglers use a specific token to mark the start
1024 of the outermost function argument tokens. Typically 'F',
1025 for ARM-demangling, for example. So if we find something
1026 we are not prepared for, it must be an error. */
1032 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1035 if (success
&& expect_func
)
1038 success
= demangle_args (work
, mangled
, declp
);
1039 /* Since template include the mangling of their return types,
1040 we must set expect_func to 0 so that we don't try do
1041 demangle more arguments the next time we get here. */
1046 if (success
&& !func_done
)
1048 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1050 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1051 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1052 first case, and need to ensure that the '(void)' gets added to
1053 the current declp. Note that with ARM, the first case
1054 represents the name of a static data member 'foo::bar',
1055 which is in the current declp, so we leave it alone. */
1056 success
= demangle_args (work
, mangled
, declp
);
1059 if (success
&& work
-> static_type
&& PRINT_ARG_TYPES
)
1060 string_append (declp
, " static");
1061 if (success
&& work
-> const_type
&& PRINT_ARG_TYPES
)
1062 string_append (declp
, " const");
1063 else if (success
&& work
->volatile_type
&& PRINT_ARG_TYPES
)
1064 string_append (declp
, " volatile");
1072 demangle_method_args (work
, mangled
, declp
)
1073 struct work_stuff
*work
;
1074 const char **mangled
;
1079 if (work
-> static_type
)
1081 string_append (declp
, *mangled
+ 1);
1082 *mangled
+= strlen (*mangled
);
1087 success
= demangle_args (work
, mangled
, declp
);
1095 demangle_template_template_parm (work
, mangled
, tname
)
1096 struct work_stuff
*work
;
1097 const char **mangled
;
1106 string_append (tname
, "template <");
1107 /* get size of template parameter list */
1108 if (get_count (mangled
, &r
))
1110 for (i
= 0; i
< r
; i
++)
1114 string_append (tname
, ", ");
1117 /* Z for type parameters */
1118 if (**mangled
== 'Z')
1121 string_append (tname
, "class");
1123 /* z for template parameters */
1124 else if (**mangled
== 'z')
1128 demangle_template_template_parm (work
, mangled
, tname
);
1136 /* temp is initialized in do_type */
1137 success
= do_type (work
, mangled
, &temp
);
1140 string_appends (tname
, &temp
);
1142 string_delete(&temp
);
1152 if (tname
->p
[-1] == '>')
1153 string_append (tname
, " ");
1154 string_append (tname
, "> class");
1159 demangle_integral_value (work
, mangled
, s
)
1160 struct work_stuff
*work
;
1161 const char** mangled
;
1166 if (**mangled
== 'E')
1168 int need_operator
= 0;
1171 string_appendn (s
, "(", 1);
1173 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1182 len
= strlen (*mangled
);
1185 i
< sizeof (optable
) / sizeof (optable
[0]);
1188 size_t l
= strlen (optable
[i
].in
);
1191 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1193 string_appendn (s
, " ", 1);
1194 string_append (s
, optable
[i
].out
);
1195 string_appendn (s
, " ", 1);
1208 success
= demangle_template_value_parm (work
, mangled
, s
,
1212 if (**mangled
!= 'W')
1216 string_appendn (s
, ")", 1);
1220 else if (**mangled
== 'Q' || **mangled
== 'K')
1221 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1226 if (**mangled
== 'm')
1228 string_appendn (s
, "-", 1);
1231 while (isdigit ((unsigned char)**mangled
))
1233 string_appendn (s
, *mangled
, 1);
1243 demangle_template_value_parm (work
, mangled
, s
, tk
)
1244 struct work_stuff
*work
;
1245 const char **mangled
;
1251 if (**mangled
== 'Y')
1253 /* The next argument is a template parameter. */
1257 idx
= consume_count_with_underscores (mangled
);
1259 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1260 || consume_count_with_underscores (mangled
) == -1)
1262 if (work
->tmpl_argvec
)
1263 string_append (s
, work
->tmpl_argvec
[idx
]);
1267 sprintf(buf
, "T%d", idx
);
1268 string_append (s
, buf
);
1271 else if (tk
== tk_integral
)
1272 success
= demangle_integral_value (work
, mangled
, s
);
1273 else if (tk
== tk_char
)
1277 if (**mangled
== 'm')
1279 string_appendn (s
, "-", 1);
1282 string_appendn (s
, "'", 1);
1283 val
= consume_count(mangled
);
1288 string_appendn (s
, &tmp
[0], 1);
1289 string_appendn (s
, "'", 1);
1291 else if (tk
== tk_bool
)
1293 int val
= consume_count (mangled
);
1295 string_appendn (s
, "false", 5);
1297 string_appendn (s
, "true", 4);
1301 else if (tk
== tk_real
)
1303 if (**mangled
== 'm')
1305 string_appendn (s
, "-", 1);
1308 while (isdigit ((unsigned char)**mangled
))
1310 string_appendn (s
, *mangled
, 1);
1313 if (**mangled
== '.') /* fraction */
1315 string_appendn (s
, ".", 1);
1317 while (isdigit ((unsigned char)**mangled
))
1319 string_appendn (s
, *mangled
, 1);
1323 if (**mangled
== 'e') /* exponent */
1325 string_appendn (s
, "e", 1);
1327 while (isdigit ((unsigned char)**mangled
))
1329 string_appendn (s
, *mangled
, 1);
1334 else if (tk
== tk_pointer
)
1336 int symbol_len
= consume_count (mangled
);
1337 if (symbol_len
== 0)
1339 if (symbol_len
== 0)
1340 string_appendn (s
, "0", 1);
1343 char *p
= xmalloc (symbol_len
+ 1), *q
;
1344 strncpy (p
, *mangled
, symbol_len
);
1345 p
[symbol_len
] = '\0';
1346 q
= internal_cplus_demangle (work
, p
);
1347 string_appendn (s
, "&", 1);
1350 string_append (s
, q
);
1354 string_append (s
, p
);
1357 *mangled
+= symbol_len
;
1363 /* Demangle the template name in MANGLED. The full name of the
1364 template (e.g., S<int>) is placed in TNAME. The name without the
1365 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1366 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1367 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1368 the tmeplate is remembered in the list of back-referenceable
1372 demangle_template (work
, mangled
, tname
, trawname
, is_type
, remember
)
1373 struct work_stuff
*work
;
1374 const char **mangled
;
1392 bindex
= register_Btype (work
);
1394 /* get template name */
1395 if (**mangled
== 'z')
1401 idx
= consume_count_with_underscores (mangled
);
1403 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1404 || consume_count_with_underscores (mangled
) == -1)
1407 if (work
->tmpl_argvec
)
1409 string_append (tname
, work
->tmpl_argvec
[idx
]);
1411 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1416 sprintf(buf
, "T%d", idx
);
1417 string_append (tname
, buf
);
1419 string_append (trawname
, buf
);
1424 if ((r
= consume_count (mangled
)) == 0
1425 || (int) strlen (*mangled
) < r
)
1429 string_appendn (tname
, *mangled
, r
);
1431 string_appendn (trawname
, *mangled
, r
);
1435 string_append (tname
, "<");
1436 /* get size of template parameter list */
1437 if (!get_count (mangled
, &r
))
1443 /* Create an array for saving the template argument values. */
1444 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
1445 work
->ntmpl_args
= r
;
1446 for (i
= 0; i
< r
; i
++)
1447 work
->tmpl_argvec
[i
] = 0;
1449 for (i
= 0; i
< r
; i
++)
1453 string_append (tname
, ", ");
1455 /* Z for type parameters */
1456 if (**mangled
== 'Z')
1459 /* temp is initialized in do_type */
1460 success
= do_type (work
, mangled
, &temp
);
1463 string_appends (tname
, &temp
);
1467 /* Save the template argument. */
1468 int len
= temp
.p
- temp
.b
;
1469 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1470 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
1471 work
->tmpl_argvec
[i
][len
] = '\0';
1474 string_delete(&temp
);
1480 /* z for template parameters */
1481 else if (**mangled
== 'z')
1485 success
= demangle_template_template_parm (work
, mangled
, tname
);
1488 && (r2
= consume_count (mangled
)) > 0
1489 && (int) strlen (*mangled
) >= r2
)
1491 string_append (tname
, " ");
1492 string_appendn (tname
, *mangled
, r2
);
1495 /* Save the template argument. */
1497 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1498 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
1499 work
->tmpl_argvec
[i
][len
] = '\0';
1513 /* otherwise, value parameter */
1515 /* temp is initialized in do_type */
1516 success
= do_type (work
, mangled
, &temp
);
1517 string_delete(&temp
);
1529 success
= demangle_template_value_parm (work
, mangled
, s
,
1530 (type_kind_t
) success
);
1542 int len
= s
->p
- s
->b
;
1543 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1544 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
1545 work
->tmpl_argvec
[i
][len
] = '\0';
1547 string_appends (tname
, s
);
1554 if (tname
->p
[-1] == '>')
1555 string_append (tname
, " ");
1556 string_append (tname
, ">");
1559 if (is_type
&& remember
)
1560 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
1563 if (work -> static_type)
1565 string_append (declp, *mangled + 1);
1566 *mangled += strlen (*mangled);
1571 success = demangle_args (work, mangled, declp);
1579 arm_pt (work
, mangled
, n
, anchor
, args
)
1580 struct work_stuff
*work
;
1581 const char *mangled
;
1583 const char **anchor
, **args
;
1586 if (ARM_DEMANGLING
&& (*anchor
= mystrstr (mangled
, "__pt__")))
1589 *args
= *anchor
+ 6;
1590 len
= consume_count (args
);
1591 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1601 demangle_arm_pt (work
, mangled
, n
, declp
)
1602 struct work_stuff
*work
;
1603 const char **mangled
;
1609 const char *e
= *mangled
+ n
;
1612 if (arm_pt (work
, *mangled
, n
, &p
, &args
))
1616 string_appendn (declp
, *mangled
, p
- *mangled
);
1617 string_append (declp
, "<");
1618 /* should do error checking here */
1620 string_clear (&arg
);
1621 do_type (work
, &args
, &arg
);
1622 string_appends (declp
, &arg
);
1623 string_append (declp
, ",");
1625 string_delete (&arg
);
1627 string_append (declp
, ">");
1629 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
1630 && (*mangled
)[9] == 'N'
1631 && (*mangled
)[8] == (*mangled
)[10]
1632 && strchr (cplus_markers
, (*mangled
)[8]))
1634 /* A member of the anonymous namespace. */
1635 string_append (declp
, "{anonymous}");
1639 string_appendn (declp
, *mangled
, n
);
1645 demangle_class_name (work
, mangled
, declp
)
1646 struct work_stuff
*work
;
1647 const char **mangled
;
1653 n
= consume_count (mangled
);
1654 if ((int) strlen (*mangled
) >= n
)
1656 demangle_arm_pt (work
, mangled
, n
, declp
);
1667 demangle_class -- demangle a mangled class sequence
1672 demangle_class (struct work_stuff *work, const char **mangled,
1677 DECLP points to the buffer into which demangling is being done.
1679 *MANGLED points to the current token to be demangled. On input,
1680 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1681 On exit, it points to the next token after the mangled class on
1682 success, or the first unconsumed token on failure.
1684 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1685 we are demangling a constructor or destructor. In this case
1686 we prepend "class::class" or "class::~class" to DECLP.
1688 Otherwise, we prepend "class::" to the current DECLP.
1690 Reset the constructor/destructor flags once they have been
1691 "consumed". This allows demangle_class to be called later during
1692 the same demangling, to do normal class demangling.
1694 Returns 1 if demangling is successful, 0 otherwise.
1699 demangle_class (work
, mangled
, declp
)
1700 struct work_stuff
*work
;
1701 const char **mangled
;
1708 string_init (&class_name
);
1709 btype
= register_Btype (work
);
1710 if (demangle_class_name (work
, mangled
, &class_name
))
1712 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1714 string_prepends (declp
, &class_name
);
1715 if (work
-> destructor
& 1)
1717 string_prepend (declp
, "~");
1718 work
-> destructor
-= 1;
1722 work
-> constructor
-= 1;
1725 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
1726 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
1727 string_prepend (declp
, SCOPE_STRING (work
));
1728 string_prepends (declp
, &class_name
);
1731 string_delete (&class_name
);
1739 demangle_prefix -- consume the mangled name prefix and find signature
1744 demangle_prefix (struct work_stuff *work, const char **mangled,
1749 Consume and demangle the prefix of the mangled name.
1751 DECLP points to the string buffer into which demangled output is
1752 placed. On entry, the buffer is empty. On exit it contains
1753 the root function name, the demangled operator name, or in some
1754 special cases either nothing or the completely demangled result.
1756 MANGLED points to the current pointer into the mangled name. As each
1757 token of the mangled name is consumed, it is updated. Upon entry
1758 the current mangled name pointer points to the first character of
1759 the mangled name. Upon exit, it should point to the first character
1760 of the signature if demangling was successful, or to the first
1761 unconsumed character if demangling of the prefix was unsuccessful.
1763 Returns 1 on success, 0 otherwise.
1767 demangle_prefix (work
, mangled
, declp
)
1768 struct work_stuff
*work
;
1769 const char **mangled
;
1776 if (strlen(*mangled
) > 6
1777 && (strncmp(*mangled
, "_imp__", 6) == 0
1778 || strncmp(*mangled
, "__imp_", 6) == 0))
1780 /* it's a symbol imported from a PE dynamic library. Check for both
1781 new style prefix _imp__ and legacy __imp_ used by older versions
1784 work
->dllimported
= 1;
1786 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
1788 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
1789 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
1791 if ((*mangled
)[9] == 'D')
1793 /* it's a GNU global destructor to be executed at program exit */
1795 work
->destructor
= 2;
1796 if (gnu_special (work
, mangled
, declp
))
1799 else if ((*mangled
)[9] == 'I')
1801 /* it's a GNU global constructor to be executed at program init */
1803 work
->constructor
= 2;
1804 if (gnu_special (work
, mangled
, declp
))
1809 else if (ARM_DEMANGLING
&& strncmp(*mangled
, "__std__", 7) == 0)
1811 /* it's a ARM global destructor to be executed at program exit */
1813 work
->destructor
= 2;
1815 else if (ARM_DEMANGLING
&& strncmp(*mangled
, "__sti__", 7) == 0)
1817 /* it's a ARM global constructor to be executed at program initial */
1819 work
->constructor
= 2;
1822 /* This block of code is a reduction in strength time optimization
1824 scan = mystrstr (*mangled, "__"); */
1830 scan
= strchr (scan
, '_');
1831 } while (scan
!= NULL
&& *++scan
!= '_');
1833 if (scan
!= NULL
) --scan
;
1838 /* We found a sequence of two or more '_', ensure that we start at
1839 the last pair in the sequence. */
1840 i
= strspn (scan
, "_");
1851 else if (work
-> static_type
)
1853 if (!isdigit ((unsigned char)scan
[0]) && (scan
[0] != 't'))
1858 else if ((scan
== *mangled
)
1859 && (isdigit ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
1860 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
1862 /* The ARM says nothing about the mangling of local variables.
1863 But cfront mangles local variables by prepending __<nesting_level>
1864 to them. As an extension to ARM demangling we handle this case. */
1865 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
)
1866 && isdigit ((unsigned char)scan
[2]))
1868 *mangled
= scan
+ 2;
1869 consume_count (mangled
);
1870 string_append (declp
, *mangled
);
1871 *mangled
+= strlen (*mangled
);
1876 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1877 names like __Q2_3foo3bar for nested type names. So don't accept
1878 this style of constructor for cfront demangling. A GNU
1879 style member-template constructor starts with 'H'. */
1880 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
))
1881 work
-> constructor
+= 1;
1882 *mangled
= scan
+ 2;
1885 else if ((scan
== *mangled
) && !isdigit ((unsigned char)scan
[2])
1886 && (scan
[2] != 't'))
1888 /* Mangled name starts with "__". Skip over any leading '_' characters,
1889 then find the next "__" that separates the prefix from the signature.
1891 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
)
1892 || (arm_special (mangled
, declp
) == 0))
1894 while (*scan
== '_')
1898 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
1900 /* No separator (I.E. "__not_mangled"), or empty signature
1901 (I.E. "__not_mangled_either__") */
1906 demangle_function_name (work
, mangled
, declp
, scan
);
1910 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
1912 /* Cfront-style parameterized type. Handled later as a signature. */
1916 demangle_arm_pt (work
, mangled
, strlen (*mangled
), declp
);
1918 else if (*(scan
+ 2) != '\0')
1920 /* Mangled name does not start with "__" but does have one somewhere
1921 in there with non empty stuff after it. Looks like a global
1923 demangle_function_name (work
, mangled
, declp
, scan
);
1927 /* Doesn't look like a mangled name */
1931 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
1933 string_append (declp
, *mangled
);
1934 *mangled
+= strlen (*mangled
);
1944 gnu_special -- special handling of gnu mangled strings
1949 gnu_special (struct work_stuff *work, const char **mangled,
1955 Process some special GNU style mangling forms that don't fit
1956 the normal pattern. For example:
1958 _$_3foo (destructor for class foo)
1959 _vt$foo (foo virtual table)
1960 _vt$foo$bar (foo::bar virtual table)
1961 __vt_foo (foo virtual table, new style with thunks)
1962 _3foo$varname (static data member)
1963 _Q22rs2tu$vw (static data member)
1964 __t6vector1Zii (constructor with template)
1965 __thunk_4__$_7ostream (virtual function thunk)
1969 gnu_special (work
, mangled
, declp
)
1970 struct work_stuff
*work
;
1971 const char **mangled
;
1978 if ((*mangled
)[0] == '_'
1979 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
1980 && (*mangled
)[2] == '_')
1982 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1984 work
-> destructor
+= 1;
1986 else if ((*mangled
)[0] == '_'
1987 && (((*mangled
)[1] == '_'
1988 && (*mangled
)[2] == 'v'
1989 && (*mangled
)[3] == 't'
1990 && (*mangled
)[4] == '_')
1991 || ((*mangled
)[1] == 'v'
1992 && (*mangled
)[2] == 't'
1993 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
1995 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1996 and create the decl. Note that we consume the entire mangled
1997 input string, which means that demangle_signature has no work
1999 if ((*mangled
)[2] == 'v')
2000 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2002 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2003 while (**mangled
!= '\0')
2005 p
= strpbrk (*mangled
, cplus_markers
);
2010 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2013 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2017 if (isdigit((unsigned char)*mangled
[0]))
2019 n
= consume_count(mangled
);
2020 /* We may be seeing a too-large size, or else a
2021 ".<digits>" indicating a static local symbol. In
2022 any case, declare victory and move on; *don't* try
2023 to use n to allocate. */
2024 if (n
> (int) strlen (*mangled
))
2032 n
= strcspn (*mangled
, cplus_markers
);
2034 string_appendn (declp
, *mangled
, n
);
2038 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2042 string_append (declp
, SCOPE_STRING (work
));
2053 string_append (declp
, " virtual table");
2055 else if ((*mangled
)[0] == '_'
2056 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2057 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2059 /* static data member, "_3foo$varname" for example */
2065 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2068 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2071 n
= consume_count (mangled
);
2072 string_appendn (declp
, *mangled
, n
);
2075 if (success
&& (p
== *mangled
))
2077 /* Consumed everything up to the cplus_marker, append the
2080 string_append (declp
, SCOPE_STRING (work
));
2081 n
= strlen (*mangled
);
2082 string_appendn (declp
, *mangled
, n
);
2090 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2092 int delta
= ((*mangled
) += 8, consume_count (mangled
));
2093 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2097 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2098 string_append (declp
, buf
);
2099 string_append (declp
, method
);
2101 n
= strlen (*mangled
);
2109 else if (strncmp (*mangled
, "__t", 3) == 0
2110 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2112 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2118 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2121 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2124 success
= demangle_fund_type (work
, mangled
, declp
);
2127 if (success
&& **mangled
!= '\0')
2130 string_append (declp
, p
);
2143 arm_special -- special handling of ARM/lucid mangled strings
2148 arm_special (const char **mangled,
2154 Process some special ARM style mangling forms that don't fit
2155 the normal pattern. For example:
2157 __vtbl__3foo (foo virtual table)
2158 __vtbl__3foo__3bar (bar::foo virtual table)
2163 arm_special (mangled
, declp
)
2164 const char **mangled
;
2171 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
2173 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2174 and create the decl. Note that we consume the entire mangled
2175 input string, which means that demangle_signature has no work
2177 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
2178 while (*scan
!= '\0') /* first check it can be demangled */
2180 n
= consume_count (&scan
);
2183 return (0); /* no good */
2186 if (scan
[0] == '_' && scan
[1] == '_')
2191 (*mangled
) += ARM_VTABLE_STRLEN
;
2192 while (**mangled
!= '\0')
2194 n
= consume_count (mangled
);
2195 string_prependn (declp
, *mangled
, n
);
2197 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
2199 string_prepend (declp
, "::");
2203 string_append (declp
, " virtual table");
2216 demangle_qualified -- demangle 'Q' qualified name strings
2221 demangle_qualified (struct work_stuff *, const char *mangled,
2222 string *result, int isfuncname, int append);
2226 Demangle a qualified name, such as "Q25Outer5Inner" which is
2227 the mangled form of "Outer::Inner". The demangled output is
2228 prepended or appended to the result string according to the
2229 state of the append flag.
2231 If isfuncname is nonzero, then the qualified name we are building
2232 is going to be used as a member function name, so if it is a
2233 constructor or destructor function, append an appropriate
2234 constructor or destructor name. I.E. for the above example,
2235 the result for use as a constructor is "Outer::Inner::Inner"
2236 and the result for use as a destructor is "Outer::Inner::~Inner".
2240 Numeric conversion is ASCII dependent (FIXME).
2245 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
2246 struct work_stuff
*work
;
2247 const char **mangled
;
2258 int bindex
= register_Btype (work
);
2260 /* We only make use of ISFUNCNAME if the entity is a constructor or
2262 isfuncname
= (isfuncname
2263 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
2265 string_init (&temp
);
2266 string_init (&last_name
);
2268 if ((*mangled
)[0] == 'K')
2270 /* Squangling qualified name reuse */
2273 idx
= consume_count_with_underscores (mangled
);
2274 if (idx
== -1 || idx
> work
-> numk
)
2277 string_append (&temp
, work
-> ktypevec
[idx
]);
2280 switch ((*mangled
)[1])
2283 /* GNU mangled name with more than 9 classes. The count is preceded
2284 by an underscore (to distinguish it from the <= 9 case) and followed
2285 by an underscore. */
2287 qualifiers
= atoi (p
);
2288 if (!isdigit ((unsigned char)*p
) || *p
== '0')
2291 /* Skip the digits. */
2292 while (isdigit ((unsigned char)*p
))
2310 /* The count is in a single digit. */
2311 num
[0] = (*mangled
)[1];
2313 qualifiers
= atoi (num
);
2315 /* If there is an underscore after the digit, skip it. This is
2316 said to be for ARM-qualified names, but the ARM makes no
2317 mention of such an underscore. Perhaps cfront uses one. */
2318 if ((*mangled
)[2] == '_')
2333 /* Pick off the names and collect them in the temp buffer in the order
2334 in which they are found, separated by '::'. */
2336 while (qualifiers
-- > 0)
2339 string_clear (&last_name
);
2341 if (*mangled
[0] == '_')
2344 if (*mangled
[0] == 't')
2346 /* Here we always append to TEMP since we will want to use
2347 the template name without the template parameters as a
2348 constructor or destructor name. The appropriate
2349 (parameter-less) value is returned by demangle_template
2350 in LAST_NAME. We do not remember the template type here,
2351 in order to match the G++ mangling algorithm. */
2352 success
= demangle_template(work
, mangled
, &temp
,
2357 else if (*mangled
[0] == 'K')
2361 idx
= consume_count_with_underscores (mangled
);
2362 if (idx
== -1 || idx
> work
->numk
)
2365 string_append (&temp
, work
->ktypevec
[idx
]);
2368 if (!success
) break;
2372 success
= do_type (work
, mangled
, &last_name
);
2375 string_appends (&temp
, &last_name
);
2379 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
2382 string_append (&temp
, SCOPE_STRING (work
));
2385 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
2387 /* If we are using the result as a function name, we need to append
2388 the appropriate '::' separated constructor or destructor name.
2389 We do this here because this is the most convenient place, where
2390 we already have a pointer to the name and the length of the name. */
2394 string_append (&temp
, SCOPE_STRING (work
));
2395 if (work
-> destructor
& 1)
2396 string_append (&temp
, "~");
2397 string_appends (&temp
, &last_name
);
2400 /* Now either prepend the temp buffer to the result, or append it,
2401 depending upon the state of the append flag. */
2404 string_appends (result
, &temp
);
2407 if (!STRING_EMPTY (result
))
2408 string_append (&temp
, SCOPE_STRING (work
));
2409 string_prepends (result
, &temp
);
2412 string_delete (&last_name
);
2413 string_delete (&temp
);
2421 get_count -- convert an ascii count to integer, consuming tokens
2426 get_count (const char **type, int *count)
2430 Return 0 if no conversion is performed, 1 if a string is converted.
2434 get_count (type
, count
)
2441 if (!isdigit ((unsigned char)**type
))
2447 *count
= **type
- '0';
2449 if (isdigit ((unsigned char)**type
))
2459 while (isdigit ((unsigned char)*p
));
2470 /* RESULT will be initialised here; it will be freed on failure. The
2471 value returned is really a type_kind_t. */
2474 do_type (work
, mangled
, result
)
2475 struct work_stuff
*work
;
2476 const char **mangled
;
2483 const char *remembered_type
;
2487 type_kind_t tk
= tk_none
;
2489 string_init (&btype
);
2490 string_init (&decl
);
2491 string_init (result
);
2495 while (success
&& !done
)
2501 /* A pointer type */
2505 string_prepend (&decl
, "*");
2510 /* A reference type */
2513 string_prepend (&decl
, "&");
2522 if (!STRING_EMPTY (&decl
)
2523 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
2525 string_prepend (&decl
, "(");
2526 string_append (&decl
, ")");
2528 string_append (&decl
, "[");
2529 if (**mangled
!= '_')
2530 success
= demangle_template_value_parm (work
, mangled
, &decl
,
2532 if (**mangled
== '_')
2534 string_append (&decl
, "]");
2538 /* A back reference to a previously seen type */
2541 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
2547 remembered_type
= work
-> typevec
[n
];
2548 mangled
= &remembered_type
;
2555 if (!STRING_EMPTY (&decl
)
2556 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
2558 string_prepend (&decl
, "(");
2559 string_append (&decl
, ")");
2561 /* After picking off the function args, we expect to either find the
2562 function return type (preceded by an '_') or the end of the
2564 if (!demangle_nested_args (work
, mangled
, &decl
)
2565 || (**mangled
!= '_' && **mangled
!= '\0'))
2570 if (success
&& (**mangled
== '_'))
2580 member
= **mangled
== 'M';
2582 if (!isdigit ((unsigned char)**mangled
) && **mangled
!= 't')
2588 string_append (&decl
, ")");
2589 string_prepend (&decl
, SCOPE_STRING (work
));
2590 if (isdigit ((unsigned char)**mangled
))
2592 n
= consume_count (mangled
);
2593 if ((int) strlen (*mangled
) < n
)
2598 string_prependn (&decl
, *mangled
, n
);
2604 string_init (&temp
);
2605 success
= demangle_template (work
, mangled
, &temp
,
2609 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
2610 string_clear (&temp
);
2615 string_prepend (&decl
, "(");
2618 if (**mangled
== 'C')
2623 if (**mangled
== 'V')
2628 if (*(*mangled
)++ != 'F')
2634 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
2635 || **mangled
!= '_')
2641 if (! PRINT_ANSI_QUALIFIERS
)
2647 APPEND_BLANK (&decl
);
2648 string_append (&decl
, "const");
2652 APPEND_BLANK (&decl
);
2653 string_append (&decl
, "volatile");
2664 if ((*mangled)[1] == 'P')
2667 if (PRINT_ANSI_QUALIFIERS
)
2669 if (!STRING_EMPTY (&decl
))
2671 string_prepend (&decl
, " ");
2673 string_prepend (&decl
,
2674 (**mangled
) == 'C' ? "const" : "volatile");
2689 if (success
) switch (**mangled
)
2691 /* A qualified name, such as "Outer::Inner". */
2695 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
2699 /* A back reference to a previously seen squangled type */
2702 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
2705 string_append (result
, work
->btypevec
[n
]);
2710 /* A template parm. We substitute the corresponding argument. */
2715 idx
= consume_count_with_underscores (mangled
);
2718 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2719 || consume_count_with_underscores (mangled
) == -1)
2725 if (work
->tmpl_argvec
)
2726 string_append (result
, work
->tmpl_argvec
[idx
]);
2730 sprintf(buf
, "T%d", idx
);
2731 string_append (result
, buf
);
2739 success
= demangle_fund_type (work
, mangled
, result
);
2741 tk
= (type_kind_t
) success
;
2747 if (!STRING_EMPTY (&decl
))
2749 string_append (result
, " ");
2750 string_appends (result
, &decl
);
2754 string_delete (result
);
2755 string_delete (&decl
);
2758 /* Assume an integral type, if we're not sure. */
2759 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
2764 /* Given a pointer to a type string that represents a fundamental type
2765 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2766 string in which the demangled output is being built in RESULT, and
2767 the WORK structure, decode the types and add them to the result.
2772 "Sl" => "signed long"
2773 "CUs" => "const unsigned short"
2775 The value returned is really a type_kind_t. */
2778 demangle_fund_type (work
, mangled
, result
)
2779 struct work_stuff
*work
;
2780 const char **mangled
;
2786 type_kind_t tk
= tk_integral
;
2788 string_init (&btype
);
2790 /* First pick off any type qualifiers. There can be more than one. */
2798 if (PRINT_ANSI_QUALIFIERS
)
2800 APPEND_BLANK (result
);
2801 string_append (result
, "const");
2806 APPEND_BLANK (result
);
2807 string_append (result
, "unsigned");
2809 case 'S': /* signed char only */
2811 APPEND_BLANK (result
);
2812 string_append (result
, "signed");
2816 if (PRINT_ANSI_QUALIFIERS
)
2818 APPEND_BLANK (result
);
2819 string_append (result
, "volatile");
2824 APPEND_BLANK (result
);
2825 string_append (result
, "__complex");
2833 /* Now pick off the fundamental type. There can be only one. */
2842 APPEND_BLANK (result
);
2843 string_append (result
, "void");
2847 APPEND_BLANK (result
);
2848 string_append (result
, "long long");
2852 APPEND_BLANK (result
);
2853 string_append (result
, "long");
2857 APPEND_BLANK (result
);
2858 string_append (result
, "int");
2862 APPEND_BLANK (result
);
2863 string_append (result
, "short");
2867 APPEND_BLANK (result
);
2868 string_append (result
, "bool");
2873 APPEND_BLANK (result
);
2874 string_append (result
, "char");
2879 APPEND_BLANK (result
);
2880 string_append (result
, "wchar_t");
2885 APPEND_BLANK (result
);
2886 string_append (result
, "long double");
2891 APPEND_BLANK (result
);
2892 string_append (result
, "double");
2897 APPEND_BLANK (result
);
2898 string_append (result
, "float");
2903 if (!isdigit ((unsigned char)**mangled
))
2909 /* An explicit type, such as "6mytype" or "7integer" */
2921 int bindex
= register_Btype (work
);
2923 string_init (&btype
);
2924 if (demangle_class_name (work
, mangled
, &btype
)) {
2925 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
2926 APPEND_BLANK (result
);
2927 string_appends (result
, &btype
);
2931 string_delete (&btype
);
2936 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
2937 string_appends (result
, &btype
);
2945 return success
? ((int) tk
) : 0;
2948 /* Demangle the next argument, given by MANGLED into RESULT, which
2949 *should be an uninitialized* string. It will be initialized here,
2950 and free'd should anything go wrong. */
2953 do_arg (work
, mangled
, result
)
2954 struct work_stuff
*work
;
2955 const char **mangled
;
2958 /* Remember where we started so that we can record the type, for
2959 non-squangling type remembering. */
2960 const char *start
= *mangled
;
2962 string_init (result
);
2964 if (work
->nrepeats
> 0)
2968 if (work
->previous_argument
== 0)
2971 /* We want to reissue the previous type in this argument list. */
2972 string_appends (result
, work
->previous_argument
);
2976 if (**mangled
== 'n')
2978 /* A squangling-style repeat. */
2980 work
->nrepeats
= consume_count(mangled
);
2982 if (work
->nrepeats
== 0)
2983 /* This was not a repeat count after all. */
2986 if (work
->nrepeats
> 9)
2988 if (**mangled
!= '_')
2989 /* The repeat count should be followed by an '_' in this
2996 /* Now, the repeat is all set up. */
2997 return do_arg (work
, mangled
, result
);
3000 /* Save the result in WORK->previous_argument so that we can find it
3001 if it's repeated. Note that saving START is not good enough: we
3002 do not want to add additional types to the back-referenceable
3003 type vector when processing a repeated type. */
3004 if (work
->previous_argument
)
3005 string_clear (work
->previous_argument
);
3008 work
->previous_argument
= (string
*) xmalloc (sizeof (string
));
3009 string_init (work
->previous_argument
);
3012 if (!do_type (work
, mangled
, work
->previous_argument
))
3015 string_appends (result
, work
->previous_argument
);
3017 remember_type (work
, start
, *mangled
- start
);
3022 remember_type (work
, start
, len
)
3023 struct work_stuff
*work
;
3029 if (work
->forgetting_types
)
3032 if (work
-> ntypes
>= work
-> typevec_size
)
3034 if (work
-> typevec_size
== 0)
3036 work
-> typevec_size
= 3;
3038 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
3042 work
-> typevec_size
*= 2;
3044 = (char **) xrealloc ((char *)work
-> typevec
,
3045 sizeof (char *) * work
-> typevec_size
);
3048 tem
= xmalloc (len
+ 1);
3049 memcpy (tem
, start
, len
);
3051 work
-> typevec
[work
-> ntypes
++] = tem
;
3055 /* Remember a K type class qualifier. */
3057 remember_Ktype (work
, start
, len
)
3058 struct work_stuff
*work
;
3064 if (work
-> numk
>= work
-> ksize
)
3066 if (work
-> ksize
== 0)
3070 = (char **) xmalloc (sizeof (char *) * work
-> ksize
);
3076 = (char **) xrealloc ((char *)work
-> ktypevec
,
3077 sizeof (char *) * work
-> ksize
);
3080 tem
= xmalloc (len
+ 1);
3081 memcpy (tem
, start
, len
);
3083 work
-> ktypevec
[work
-> numk
++] = tem
;
3086 /* Register a B code, and get an index for it. B codes are registered
3087 as they are seen, rather than as they are completed, so map<temp<char> >
3088 registers map<temp<char> > as B0, and temp<char> as B1 */
3091 register_Btype (work
)
3092 struct work_stuff
*work
;
3096 if (work
-> numb
>= work
-> bsize
)
3098 if (work
-> bsize
== 0)
3102 = (char **) xmalloc (sizeof (char *) * work
-> bsize
);
3108 = (char **) xrealloc ((char *)work
-> btypevec
,
3109 sizeof (char *) * work
-> bsize
);
3112 ret
= work
-> numb
++;
3113 work
-> btypevec
[ret
] = NULL
;
3117 /* Store a value into a previously registered B code type. */
3120 remember_Btype (work
, start
, len
, index
)
3121 struct work_stuff
*work
;
3127 tem
= xmalloc (len
+ 1);
3128 memcpy (tem
, start
, len
);
3130 work
-> btypevec
[index
] = tem
;
3133 /* Lose all the info related to B and K type codes. */
3135 forget_B_and_K_types (work
)
3136 struct work_stuff
*work
;
3140 while (work
-> numk
> 0)
3142 i
= --(work
-> numk
);
3143 if (work
-> ktypevec
[i
] != NULL
)
3145 free (work
-> ktypevec
[i
]);
3146 work
-> ktypevec
[i
] = NULL
;
3150 while (work
-> numb
> 0)
3152 i
= --(work
-> numb
);
3153 if (work
-> btypevec
[i
] != NULL
)
3155 free (work
-> btypevec
[i
]);
3156 work
-> btypevec
[i
] = NULL
;
3160 /* Forget the remembered types, but not the type vector itself. */
3164 struct work_stuff
*work
;
3168 while (work
-> ntypes
> 0)
3170 i
= --(work
-> ntypes
);
3171 if (work
-> typevec
[i
] != NULL
)
3173 free (work
-> typevec
[i
]);
3174 work
-> typevec
[i
] = NULL
;
3179 /* Process the argument list part of the signature, after any class spec
3180 has been consumed, as well as the first 'F' character (if any). For
3183 "__als__3fooRT0" => process "RT0"
3184 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3186 DECLP must be already initialised, usually non-empty. It won't be freed
3189 Note that g++ differs significantly from ARM and lucid style mangling
3190 with regards to references to previously seen types. For example, given
3191 the source fragment:
3195 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3198 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3199 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3201 g++ produces the names:
3206 while lcc (and presumably other ARM style compilers as well) produces:
3208 foo__FiR3fooT1T2T1T2
3209 __ct__3fooFiR3fooT1T2T1T2
3211 Note that g++ bases its type numbers starting at zero and counts all
3212 previously seen types, while lucid/ARM bases its type numbers starting
3213 at one and only considers types after it has seen the 'F' character
3214 indicating the start of the function args. For lucid/ARM style, we
3215 account for this difference by discarding any previously seen types when
3216 we see the 'F' character, and subtracting one from the type number
3222 demangle_args (work
, mangled
, declp
)
3223 struct work_stuff
*work
;
3224 const char **mangled
;
3234 if (PRINT_ARG_TYPES
)
3236 string_append (declp
, "(");
3237 if (**mangled
== '\0')
3239 string_append (declp
, "void");
3243 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
3244 || work
->nrepeats
> 0)
3246 if ((**mangled
== 'N') || (**mangled
== 'T'))
3248 temptype
= *(*mangled
)++;
3250 if (temptype
== 'N')
3252 if (!get_count (mangled
, &r
))
3261 if (ARM_DEMANGLING
&& work
-> ntypes
>= 10)
3263 /* If we have 10 or more types we might have more than a 1 digit
3264 index so we'll have to consume the whole count here. This
3265 will lose if the next thing is a type name preceded by a
3266 count but it's impossible to demangle that case properly
3267 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3268 Pc, ...)" or "(..., type12, char *, ...)" */
3269 if ((t
= consume_count(mangled
)) == 0)
3276 if (!get_count (mangled
, &t
))
3281 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
)
3285 /* Validate the type index. Protect against illegal indices from
3286 malformed type strings. */
3287 if ((t
< 0) || (t
>= work
-> ntypes
))
3291 while (work
->nrepeats
> 0 || --r
>= 0)
3293 tem
= work
-> typevec
[t
];
3294 if (need_comma
&& PRINT_ARG_TYPES
)
3296 string_append (declp
, ", ");
3298 if (!do_arg (work
, &tem
, &arg
))
3302 if (PRINT_ARG_TYPES
)
3304 string_appends (declp
, &arg
);
3306 string_delete (&arg
);
3312 if (need_comma
&& PRINT_ARG_TYPES
)
3313 string_append (declp
, ", ");
3314 if (!do_arg (work
, mangled
, &arg
))
3316 if (PRINT_ARG_TYPES
)
3317 string_appends (declp
, &arg
);
3318 string_delete (&arg
);
3323 if (**mangled
== 'e')
3326 if (PRINT_ARG_TYPES
)
3330 string_append (declp
, ",");
3332 string_append (declp
, "...");
3336 if (PRINT_ARG_TYPES
)
3338 string_append (declp
, ")");
3343 /* Like demangle_args, but for demangling the argument lists of function
3344 and method pointers or references, not top-level declarations. */
3347 demangle_nested_args (work
, mangled
, declp
)
3348 struct work_stuff
*work
;
3349 const char **mangled
;
3352 string
* saved_previous_argument
;
3356 /* The G++ name-mangling algorithm does not remember types on nested
3357 argument lists, unless -fsquangling is used, and in that case the
3358 type vector updated by remember_type is not used. So, we turn
3359 off remembering of types here. */
3360 ++work
->forgetting_types
;
3362 /* For the repeat codes used with -fsquangling, we must keep track of
3363 the last argument. */
3364 saved_previous_argument
= work
->previous_argument
;
3365 saved_nrepeats
= work
->nrepeats
;
3366 work
->previous_argument
= 0;
3369 /* Actually demangle the arguments. */
3370 result
= demangle_args (work
, mangled
, declp
);
3372 /* Restore the previous_argument field. */
3373 if (work
->previous_argument
)
3374 string_delete (work
->previous_argument
);
3375 work
->previous_argument
= saved_previous_argument
;
3376 work
->nrepeats
= saved_nrepeats
;
3382 demangle_function_name (work
, mangled
, declp
, scan
)
3383 struct work_stuff
*work
;
3384 const char **mangled
;
3392 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
3393 string_need (declp
, 1);
3394 *(declp
-> p
) = '\0';
3396 /* Consume the function name, including the "__" separating the name
3397 from the signature. We are guaranteed that SCAN points to the
3400 (*mangled
) = scan
+ 2;
3402 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
)
3405 /* See if we have an ARM style constructor or destructor operator.
3406 If so, then just record it, clear the decl, and return.
3407 We can't build the actual constructor/destructor decl until later,
3408 when we recover the class name from the signature. */
3410 if (strcmp (declp
-> b
, "__ct") == 0)
3412 work
-> constructor
+= 1;
3413 string_clear (declp
);
3416 else if (strcmp (declp
-> b
, "__dt") == 0)
3418 work
-> destructor
+= 1;
3419 string_clear (declp
);
3424 if (declp
->p
- declp
->b
>= 3
3425 && declp
->b
[0] == 'o'
3426 && declp
->b
[1] == 'p'
3427 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
3429 /* see if it's an assignment expression */
3430 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
3431 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
3433 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
3435 int len
= declp
->p
- declp
->b
- 10;
3436 if ((int) strlen (optable
[i
].in
) == len
3437 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
3439 string_clear (declp
);
3440 string_append (declp
, "operator");
3441 string_append (declp
, optable
[i
].out
);
3442 string_append (declp
, "=");
3449 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
3451 int len
= declp
->p
- declp
->b
- 3;
3452 if ((int) strlen (optable
[i
].in
) == len
3453 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
3455 string_clear (declp
);
3456 string_append (declp
, "operator");
3457 string_append (declp
, optable
[i
].out
);
3463 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
3464 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
3466 /* type conversion operator */
3468 if (do_type (work
, &tem
, &type
))
3470 string_clear (declp
);
3471 string_append (declp
, "operator ");
3472 string_appends (declp
, &type
);
3473 string_delete (&type
);
3476 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
3477 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
3480 /* type conversion operator. */
3482 if (do_type (work
, &tem
, &type
))
3484 string_clear (declp
);
3485 string_append (declp
, "operator ");
3486 string_appends (declp
, &type
);
3487 string_delete (&type
);
3490 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
3491 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
3492 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
3494 if (declp
->b
[4] == '\0')
3497 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
3499 if (strlen (optable
[i
].in
) == 2
3500 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
3502 string_clear (declp
);
3503 string_append (declp
, "operator");
3504 string_append (declp
, optable
[i
].out
);
3511 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
3514 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
3516 if (strlen (optable
[i
].in
) == 3
3517 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
3519 string_clear (declp
);
3520 string_append (declp
, "operator");
3521 string_append (declp
, optable
[i
].out
);
3530 /* a mini string-handling package */
3545 s
->p
= s
->b
= xmalloc (n
);
3548 else if (s
->e
- s
->p
< n
)
3553 s
->b
= xrealloc (s
->b
, n
);
3566 s
->b
= s
->e
= s
->p
= NULL
;
3574 s
->b
= s
->p
= s
->e
= NULL
;
3590 return (s
->b
== s
->p
);
3596 string_append (p
, s
)
3601 if (s
== NULL
|| *s
== '\0')
3605 memcpy (p
->p
, s
, n
);
3610 string_appends (p
, s
)
3619 memcpy (p
->p
, s
->b
, n
);
3625 string_appendn (p
, s
, n
)
3633 memcpy (p
->p
, s
, n
);
3639 string_prepend (p
, s
)
3643 if (s
!= NULL
&& *s
!= '\0')
3645 string_prependn (p
, s
, strlen (s
));
3650 string_prepends (p
, s
)
3655 string_prependn (p
, s
->b
, s
->p
- s
->b
);
3660 string_prependn (p
, s
, n
)
3670 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
3674 memcpy (p
->b
, s
, n
);
3679 /* To generate a standalone demangler program for testing purposes,
3680 just compile and link this file with -DMAIN and libiberty.a. When
3681 run, it demangles each command line arg, or each stdin string, and
3682 prints the result on stdout. */
3688 static char *program_name
;
3689 static char *program_version
= VERSION
;
3690 static int flags
= DMGL_PARAMS
| DMGL_ANSI
;
3692 static void demangle_it
PARAMS ((char *));
3693 static void usage
PARAMS ((FILE *, int));
3694 static void fatal
PARAMS ((char *));
3697 demangle_it (mangled_name
)
3702 result
= cplus_demangle (mangled_name
, flags
);
3705 printf ("%s\n", mangled_name
);
3709 printf ("%s\n", result
);
3715 usage (stream
, status
)
3720 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3721 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3722 [--help] [--version] [arg...]\n",
3727 #define MBUF_SIZE 32767
3728 char mbuffer
[MBUF_SIZE
];
3730 /* Defined in the automatically-generated underscore.c. */
3731 extern int prepends_underscore
;
3733 int strip_underscore
= 0;
3735 static struct option long_options
[] = {
3736 {"strip-underscores", no_argument
, 0, '_'},
3737 {"format", required_argument
, 0, 's'},
3738 {"help", no_argument
, 0, 'h'},
3739 {"no-strip-underscores", no_argument
, 0, 'n'},
3740 {"version", no_argument
, 0, 'v'},
3741 {0, no_argument
, 0, 0}
3744 /* More 'friendly' abort that prints the line and file.
3745 config.h can #define abort fancy_abort if you like that sort of thing. */
3750 fatal ("Internal gcc abort.");
3761 program_name
= argv
[0];
3763 strip_underscore
= prepends_underscore
;
3765 while ((c
= getopt_long (argc
, argv
, "_ns:j", long_options
, (int *) 0)) != EOF
)
3775 strip_underscore
= 0;
3778 printf ("GNU %s version %s\n", program_name
, program_version
);
3781 strip_underscore
= 1;
3784 if (strcmp (optarg
, "gnu") == 0)
3786 current_demangling_style
= gnu_demangling
;
3788 else if (strcmp (optarg
, "lucid") == 0)
3790 current_demangling_style
= lucid_demangling
;
3792 else if (strcmp (optarg
, "arm") == 0)
3794 current_demangling_style
= arm_demangling
;
3798 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
3799 program_name
, optarg
);
3808 for ( ; optind
< argc
; optind
++)
3810 demangle_it (argv
[optind
]);
3819 /* Try to read a label. */
3820 while (c
!= EOF
&& (isalnum(c
) || c
== '_' || c
== '$' || c
== '.'))
3822 if (i
>= MBUF_SIZE
-1)
3831 if (mbuffer
[0] == '.')
3833 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
3841 result
= cplus_demangle (mbuffer
+ skip_first
, flags
);
3844 if (mbuffer
[0] == '.')
3846 fputs (result
, stdout
);
3850 fputs (mbuffer
, stdout
);
3867 fprintf (stderr
, "%s: %s\n", program_name
, str
);
3875 register char *value
= (char *) malloc (size
);
3877 fatal ("virtual memory exhausted");
3882 xrealloc (ptr
, size
)
3886 register char *value
= (char *) realloc (ptr
, size
);
3888 fatal ("virtual memory exhausted");