1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997 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 #undef CURRENT_DEMANGLING_STYLE
37 #define CURRENT_DEMANGLING_STYLE work->options
39 extern char *xmalloc
PARAMS((unsigned));
40 extern char *xrealloc
PARAMS((char *, unsigned));
42 static const char *mystrstr
PARAMS ((const char *, const char *));
48 register const char *p
= s1
;
49 register int len
= strlen (s2
);
51 for (; (p
= strchr (p
, *s2
)) != 0; p
++)
53 if (strncmp (p
, s2
, len
) == 0)
61 /* In order to allow a single demangler executable to demangle strings
62 using various common values of CPLUS_MARKER, as well as any specific
63 one set at compile time, we maintain a string containing all the
64 commonly used ones, and check to see if the marker we are looking for
65 is in that string. CPLUS_MARKER is usually '$' on systems where the
66 assembler can deal with that. Where the assembler can't, it's usually
67 '.' (but on many systems '.' is used for other things). We put the
68 current defined CPLUS_MARKER first (which defaults to '$'), followed
69 by the next most common value, followed by an explicit '$' in case
70 the value of CPLUS_MARKER is not '$'.
72 We could avoid this if we could just get g++ to tell us what the actual
73 cplus marker character is as part of the debug information, perhaps by
74 ensuring that it is the character that terminates the gcc<n>_compiled
75 marker symbol (FIXME). */
77 #if !defined (CPLUS_MARKER)
78 #define CPLUS_MARKER '$'
81 enum demangling_styles current_demangling_style
= gnu_demangling
;
83 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
86 set_cplus_marker_for_demangling (ch
)
89 cplus_markers
[0] = ch
;
92 /* Stuff that is shared between sub-routines.
93 Using a shared structure allows cplus_demangle to be reentrant. */
103 int static_type
; /* A static member function */
104 int const_type
; /* A const member function */
105 char **tmpl_argvec
; /* Template function arguments. */
106 int ntmpl_args
; /* The number of template function arguments. */
109 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
110 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
112 static const struct optable
118 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
119 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
120 {"new", " new", 0}, /* old (1.91, and 1.x) */
121 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
122 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
123 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
124 {"as", "=", DMGL_ANSI
}, /* ansi */
125 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
126 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
127 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
128 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
129 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
130 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
131 {"plus", "+", 0}, /* old */
132 {"pl", "+", DMGL_ANSI
}, /* ansi */
133 {"apl", "+=", DMGL_ANSI
}, /* ansi */
134 {"minus", "-", 0}, /* old */
135 {"mi", "-", DMGL_ANSI
}, /* ansi */
136 {"ami", "-=", DMGL_ANSI
}, /* ansi */
137 {"mult", "*", 0}, /* old */
138 {"ml", "*", DMGL_ANSI
}, /* ansi */
139 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
140 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
141 {"convert", "+", 0}, /* old (unary +) */
142 {"negate", "-", 0}, /* old (unary -) */
143 {"trunc_mod", "%", 0}, /* old */
144 {"md", "%", DMGL_ANSI
}, /* ansi */
145 {"amd", "%=", DMGL_ANSI
}, /* ansi */
146 {"trunc_div", "/", 0}, /* old */
147 {"dv", "/", DMGL_ANSI
}, /* ansi */
148 {"adv", "/=", DMGL_ANSI
}, /* ansi */
149 {"truth_andif", "&&", 0}, /* old */
150 {"aa", "&&", DMGL_ANSI
}, /* ansi */
151 {"truth_orif", "||", 0}, /* old */
152 {"oo", "||", DMGL_ANSI
}, /* ansi */
153 {"truth_not", "!", 0}, /* old */
154 {"nt", "!", DMGL_ANSI
}, /* ansi */
155 {"postincrement","++", 0}, /* old */
156 {"pp", "++", DMGL_ANSI
}, /* ansi */
157 {"postdecrement","--", 0}, /* old */
158 {"mm", "--", DMGL_ANSI
}, /* ansi */
159 {"bit_ior", "|", 0}, /* old */
160 {"or", "|", DMGL_ANSI
}, /* ansi */
161 {"aor", "|=", DMGL_ANSI
}, /* ansi */
162 {"bit_xor", "^", 0}, /* old */
163 {"er", "^", DMGL_ANSI
}, /* ansi */
164 {"aer", "^=", DMGL_ANSI
}, /* ansi */
165 {"bit_and", "&", 0}, /* old */
166 {"ad", "&", DMGL_ANSI
}, /* ansi */
167 {"aad", "&=", DMGL_ANSI
}, /* ansi */
168 {"bit_not", "~", 0}, /* old */
169 {"co", "~", DMGL_ANSI
}, /* ansi */
170 {"call", "()", 0}, /* old */
171 {"cl", "()", DMGL_ANSI
}, /* ansi */
172 {"alshift", "<<", 0}, /* old */
173 {"ls", "<<", DMGL_ANSI
}, /* ansi */
174 {"als", "<<=", DMGL_ANSI
}, /* ansi */
175 {"arshift", ">>", 0}, /* old */
176 {"rs", ">>", DMGL_ANSI
}, /* ansi */
177 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
178 {"component", "->", 0}, /* old */
179 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
180 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
181 {"indirect", "*", 0}, /* old */
182 {"method_call", "->()", 0}, /* old */
183 {"addr", "&", 0}, /* old (unary &) */
184 {"array", "[]", 0}, /* old */
185 {"vc", "[]", DMGL_ANSI
}, /* ansi */
186 {"compound", ", ", 0}, /* old */
187 {"cm", ", ", DMGL_ANSI
}, /* ansi */
188 {"cond", "?:", 0}, /* old */
189 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
190 {"max", ">?", 0}, /* old */
191 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
192 {"min", "<?", 0}, /* old */
193 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
194 {"nop", "", 0}, /* old (for operator=) */
195 {"rm", "->*", DMGL_ANSI
}, /* ansi */
196 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
200 typedef struct string
/* Beware: these aren't required to be */
201 { /* '\0' terminated. */
202 char *b
; /* pointer to start of string */
203 char *p
; /* pointer after last character */
204 char *e
; /* pointer after end of allocated space */
207 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
208 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
209 string_prepend(str, " ");}
210 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
211 string_append(str, " ");}
213 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
214 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
216 /* Prototypes for local functions */
219 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
223 demangle_method_args
PARAMS ((struct work_stuff
*work
, const char **, string
*));
227 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*,
231 arm_pt
PARAMS ((struct work_stuff
*, const char *, int, const char **,
235 demangle_arm_pt
PARAMS ((struct work_stuff
*, const char **, int, string
*));
238 demangle_class_name
PARAMS ((struct work_stuff
*, const char **, string
*));
241 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
245 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
248 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
251 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
254 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
257 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
260 arm_special
PARAMS ((struct work_stuff
*, const char **, string
*));
263 string_need
PARAMS ((string
*, int));
266 string_delete
PARAMS ((string
*));
269 string_init
PARAMS ((string
*));
272 string_clear
PARAMS ((string
*));
276 string_empty
PARAMS ((string
*));
280 string_append
PARAMS ((string
*, const char *));
283 string_appends
PARAMS ((string
*, string
*));
286 string_appendn
PARAMS ((string
*, const char *, int));
289 string_prepend
PARAMS ((string
*, const char *));
292 string_prependn
PARAMS ((string
*, const char *, int));
295 get_count
PARAMS ((const char **, int *));
298 consume_count
PARAMS ((const char **));
301 consume_count_with_underscores
PARAMS ((const char**));
304 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
307 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
310 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
313 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
317 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
320 forget_types
PARAMS ((struct work_stuff
*));
323 string_prepends
PARAMS ((string
*, string
*));
326 demangle_template_value_parm
PARAMS ((struct work_stuff
*,
327 const char**, string
*));
329 /* Translate count to integer, consuming tokens in the process.
330 Conversion terminates on the first non-digit character.
331 Trying to consume something that isn't a count results in
332 no consumption of input and a return of 0. */
340 while (isdigit (**type
))
343 count
+= **type
- '0';
350 /* Like consume_count, but for counts that are preceeded and followed
351 by '_' if they are greater than 10. Also, -1 is returned for
352 failure, since 0 can be a valid value. */
355 consume_count_with_underscores (mangled
)
356 const char **mangled
;
360 if (**mangled
== '_')
363 if (!isdigit (**mangled
))
366 idx
= consume_count (mangled
);
367 if (**mangled
!= '_')
368 /* The trailing underscore was missing. */
375 if (**mangled
< '0' || **mangled
> '9')
378 idx
= **mangled
- '0';
386 cplus_demangle_opname (opname
, result
, options
)
391 int len
, i
, len1
, ret
;
393 struct work_stuff work
[1];
396 len
= strlen(opname
);
399 work
->options
= options
;
401 if (opname
[0] == '_' && opname
[1] == '_'
402 && opname
[2] == 'o' && opname
[3] == 'p')
405 /* type conversion operator. */
407 if (do_type (work
, &tem
, &type
))
409 strcat (result
, "operator ");
410 strncat (result
, type
.b
, type
.p
- type
.b
);
411 string_delete (&type
);
415 else if (opname
[0] == '_' && opname
[1] == '_'
416 && opname
[2] >= 'a' && opname
[2] <= 'z'
417 && opname
[3] >= 'a' && opname
[3] <= 'z')
419 if (opname
[4] == '\0')
422 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
424 if (strlen (optable
[i
].in
) == 2
425 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
427 strcat (result
, "operator");
428 strcat (result
, optable
[i
].out
);
436 if (opname
[2] == 'a' && opname
[5] == '\0')
439 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
441 if (strlen (optable
[i
].in
) == 3
442 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
444 strcat (result
, "operator");
445 strcat (result
, optable
[i
].out
);
456 && strchr (cplus_markers
, opname
[2]) != NULL
)
458 /* see if it's an assignment expression */
459 if (len
>= 10 /* op$assign_ */
460 && memcmp (opname
+ 3, "assign_", 7) == 0)
462 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
465 if (strlen (optable
[i
].in
) == len1
466 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
468 strcat (result
, "operator");
469 strcat (result
, optable
[i
].out
);
470 strcat (result
, "=");
478 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
481 if (strlen (optable
[i
].in
) == len1
482 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
484 strcat (result
, "operator");
485 strcat (result
, optable
[i
].out
);
492 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
493 && strchr (cplus_markers
, opname
[4]) != NULL
)
495 /* type conversion operator */
497 if (do_type (work
, &tem
, &type
))
499 strcat (result
, "operator ");
500 strncat (result
, type
.b
, type
.p
- type
.b
);
501 string_delete (&type
);
508 /* Takes operator name as e.g. "++" and returns mangled
509 operator name (e.g. "postincrement_expr"), or NULL if not found.
511 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
512 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
515 cplus_mangle_opname (opname
, options
)
522 len
= strlen (opname
);
523 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
525 if (strlen (optable
[i
].out
) == len
526 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
527 && memcmp (optable
[i
].out
, opname
, len
) == 0)
528 return optable
[i
].in
;
533 /* char *cplus_demangle (const char *mangled, int options)
535 If MANGLED is a mangled function name produced by GNU C++, then
536 a pointer to a malloced string giving a C++ representation
537 of the name will be returned; otherwise NULL will be returned.
538 It is the caller's responsibility to free the string which
541 The OPTIONS arg may contain one or more of the following bits:
543 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
545 DMGL_PARAMS Function parameters are included.
549 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
550 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
551 cplus_demangle ("foo__1Ai", 0) => "A::foo"
553 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
554 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
555 cplus_demangle ("foo__1Afe", 0) => "A::foo"
557 Note that any leading underscores, or other such characters prepended by
558 the compilation system, are presumed to have already been stripped from
562 cplus_demangle (mangled
, options
)
568 struct work_stuff work
[1];
569 char *demangled
= NULL
;
571 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
573 memset ((char *) work
, 0, sizeof (work
));
574 work
-> options
= options
;
575 if ((work
->options
& DMGL_STYLE_MASK
) == 0)
576 work
->options
|= (int)current_demangling_style
& DMGL_STYLE_MASK
;
580 /* First check to see if gnu style demangling is active and if the
581 string to be demangled contains a CPLUS_MARKER. If so, attempt to
582 recognize one of the gnu special forms rather than looking for a
583 standard prefix. In particular, don't worry about whether there
584 is a "__" string in the mangled string. Consider "_$_5__foo" for
587 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
589 success
= gnu_special (work
, &mangled
, &decl
);
593 success
= demangle_prefix (work
, &mangled
, &decl
);
595 if (success
&& (*mangled
!= '\0'))
597 success
= demangle_signature (work
, &mangled
, &decl
);
599 if (work
->constructor
== 2)
601 string_prepend(&decl
, "global constructors keyed to ");
602 work
->constructor
= 0;
604 else if (work
->destructor
== 2)
606 string_prepend(&decl
, "global destructors keyed to ");
607 work
->destructor
= 0;
609 demangled
= mop_up (work
, &decl
, success
);
615 mop_up (work
, declp
, success
)
616 struct work_stuff
*work
;
620 char *demangled
= NULL
;
622 /* Discard the remembered types, if any. */
625 if (work
-> typevec
!= NULL
)
627 free ((char *) work
-> typevec
);
629 if (work
->tmpl_argvec
)
633 for (i
= 0; i
< work
->ntmpl_args
; i
++)
634 if (work
->tmpl_argvec
[i
])
635 free ((char*) work
->tmpl_argvec
[i
]);
637 free ((char*) work
->tmpl_argvec
);
640 /* If demangling was successful, ensure that the demangled string is null
641 terminated and return it. Otherwise, free the demangling decl. */
645 string_delete (declp
);
649 string_appendn (declp
, "", 1);
650 demangled
= declp
-> b
;
659 demangle_signature -- demangle the signature part of a mangled name
664 demangle_signature (struct work_stuff *work, const char **mangled,
669 Consume and demangle the signature portion of the mangled name.
671 DECLP is the string where demangled output is being built. At
672 entry it contains the demangled root name from the mangled name
673 prefix. I.E. either a demangled operator name or the root function
674 name. In some special cases, it may contain nothing.
676 *MANGLED points to the current unconsumed location in the mangled
677 name. As tokens are consumed and demangling is performed, the
678 pointer is updated to continuously point at the next token to
681 Demangling GNU style mangled names is nasty because there is no
682 explicit token that marks the start of the outermost function
686 demangle_signature (work
, mangled
, declp
)
687 struct work_stuff
*work
;
688 const char **mangled
;
694 int expect_return_type
= 0;
695 const char *oldmangled
= NULL
;
699 while (success
&& (**mangled
!= '\0'))
704 oldmangled
= *mangled
;
705 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
708 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
710 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
718 /* Static member function */
719 if (oldmangled
== NULL
)
721 oldmangled
= *mangled
;
724 work
-> static_type
= 1;
728 /* a const member function */
729 if (oldmangled
== NULL
)
731 oldmangled
= *mangled
;
734 work
-> const_type
= 1;
737 case '0': case '1': case '2': case '3': case '4':
738 case '5': case '6': case '7': case '8': case '9':
739 if (oldmangled
== NULL
)
741 oldmangled
= *mangled
;
743 success
= demangle_class (work
, mangled
, declp
);
746 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
748 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
757 /* ARM style demangling includes a specific 'F' character after
758 the class name. For GNU style, it is just implied. So we can
759 safely just consume any 'F' at this point and be compatible
760 with either style. */
766 /* For lucid/ARM style we have to forget any types we might
767 have remembered up to this point, since they were not argument
768 types. GNU style considers all types seen as available for
769 back references. See comment in demangle_args() */
771 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
)
775 success
= demangle_args (work
, mangled
, declp
);
780 string_init(&trawname
);
782 if (oldmangled
== NULL
)
784 oldmangled
= *mangled
;
786 success
= demangle_template (work
, mangled
, &tname
, &trawname
, 1);
789 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
791 string_append(&tname
, (work
-> options
& DMGL_JAVA
) ? "." : "::");
792 string_prepends(declp
, &tname
);
793 if (work
-> destructor
& 1)
795 string_prepend (&trawname
, "~");
796 string_appends (declp
, &trawname
);
797 work
->destructor
-= 1;
799 if ((work
->constructor
& 1) || (work
->destructor
& 1))
801 string_appends (declp
, &trawname
);
802 work
->constructor
-= 1;
804 string_delete(&trawname
);
805 string_delete(&tname
);
811 if (GNU_DEMANGLING
&& expect_return_type
)
813 /* Read the return type. */
815 string_init (&return_type
);
818 success
= do_type (work
, mangled
, &return_type
);
819 APPEND_BLANK (&return_type
);
821 string_prepends (declp
, &return_type
);
822 string_delete (&return_type
);
826 /* At the outermost level, we cannot have a return type specified,
827 so if we run into another '_' at this point we are dealing with
828 a mangled name that is either bogus, or has been mangled by
829 some algorithm we don't know how to deal with. So just
830 reject the entire demangling. */
837 /* A G++ template function. Read the template arguments. */
838 success
= demangle_template (work
, mangled
, declp
, 0, 0);
839 if (!(work
->constructor
& 1))
840 expect_return_type
= 1;
849 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
851 /* Assume we have stumbled onto the first outermost function
852 argument token, and start processing args. */
854 success
= demangle_args (work
, mangled
, declp
);
858 /* Non-GNU demanglers use a specific token to mark the start
859 of the outermost function argument tokens. Typically 'F',
860 for ARM-demangling, for example. So if we find something
861 we are not prepared for, it must be an error. */
867 if (AUTO_DEMANGLING || GNU_DEMANGLING)
870 if (success
&& expect_func
)
873 success
= demangle_args (work
, mangled
, declp
);
874 /* Since template include the mangling of their return types,
875 we must set expect_func to 0 so that we don't try do
876 demangle more arguments the next time we get here. */
881 if (success
&& !func_done
)
883 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
885 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
886 bar__3fooi is 'foo::bar(int)'. We get here when we find the
887 first case, and need to ensure that the '(void)' gets added to
888 the current declp. Note that with ARM, the first case
889 represents the name of a static data member 'foo::bar',
890 which is in the current declp, so we leave it alone. */
891 success
= demangle_args (work
, mangled
, declp
);
894 if (success
&& work
-> static_type
&& PRINT_ARG_TYPES
)
896 string_append (declp
, " static");
898 if (success
&& work
-> const_type
&& PRINT_ARG_TYPES
)
900 string_append (declp
, " const");
908 demangle_method_args (work
, mangled
, declp
)
909 struct work_stuff
*work
;
910 const char **mangled
;
915 if (work
-> static_type
)
917 string_append (declp
, *mangled
+ 1);
918 *mangled
+= strlen (*mangled
);
923 success
= demangle_args (work
, mangled
, declp
);
931 demangle_integral_value (work
, mangled
, s
)
932 struct work_stuff
*work
;
933 const char** mangled
;
938 if (**mangled
== 'E')
940 int need_operator
= 0;
943 string_appendn (s
, "(", 1);
945 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
954 len
= strlen (*mangled
);
957 i
< sizeof (optable
) / sizeof (optable
[0]);
960 size_t l
= strlen (optable
[i
].in
);
963 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
965 string_appendn (s
, " ", 1);
966 string_append (s
, optable
[i
].out
);
967 string_appendn (s
, " ", 1);
980 success
= demangle_template_value_parm (work
, mangled
, s
);
983 if (**mangled
!= 'W')
987 string_appendn (s
, ")", 1);
991 else if (**mangled
== 'Q')
992 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
997 if (**mangled
== 'm')
999 string_appendn (s
, "-", 1);
1002 while (isdigit (**mangled
))
1004 string_appendn (s
, *mangled
, 1);
1014 demangle_template_value_parm (work
, mangled
, s
)
1015 struct work_stuff
*work
;
1016 const char **mangled
;
1019 const char *old_p
= *mangled
;
1022 int is_integral
= 0;
1028 while (*old_p
&& !done
)
1035 done
= is_pointer
= 1;
1037 case 'C': /* const */
1038 case 'S': /* explicitly signed [char] */
1039 case 'U': /* unsigned */
1040 case 'V': /* volatile */
1041 case 'F': /* function */
1042 case 'M': /* member function */
1044 case 'J': /* complex */
1047 case 'E': /* expression */
1048 case 'Q': /* qualified name */
1049 done
= is_integral
= 1;
1051 case 'T': /* remembered type */
1054 case 'v': /* void */
1057 case 'x': /* long long */
1058 case 'l': /* long */
1060 case 's': /* short */
1061 case 'w': /* wchar_t */
1062 done
= is_integral
= 1;
1064 case 'b': /* bool */
1067 case 'c': /* char */
1070 case 'r': /* long double */
1071 case 'd': /* double */
1072 case 'f': /* float */
1076 /* it's probably user defined type, let's assume
1077 it's integral, it seems hard to figure out
1078 what it really is */
1079 done
= is_integral
= 1;
1082 if (**mangled
== 'Y')
1084 /* The next argument is a template parameter. */
1088 idx
= consume_count_with_underscores (mangled
);
1090 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1091 || consume_count_with_underscores (mangled
) == -1)
1093 if (work
->tmpl_argvec
)
1094 string_append (s
, work
->tmpl_argvec
[idx
]);
1098 sprintf(buf
, "T%d", idx
);
1099 string_append (s
, buf
);
1102 else if (is_integral
)
1103 success
= demangle_integral_value (work
, mangled
, s
);
1108 if (**mangled
== 'm')
1110 string_appendn (s
, "-", 1);
1113 string_appendn (s
, "'", 1);
1114 val
= consume_count(mangled
);
1119 string_appendn (s
, &tmp
[0], 1);
1120 string_appendn (s
, "'", 1);
1124 int val
= consume_count (mangled
);
1126 string_appendn (s
, "false", 5);
1128 string_appendn (s
, "true", 4);
1134 if (**mangled
== 'm')
1136 string_appendn (s
, "-", 1);
1139 while (isdigit (**mangled
))
1141 string_appendn (s
, *mangled
, 1);
1144 if (**mangled
== '.') /* fraction */
1146 string_appendn (s
, ".", 1);
1148 while (isdigit (**mangled
))
1150 string_appendn (s
, *mangled
, 1);
1154 if (**mangled
== 'e') /* exponent */
1156 string_appendn (s
, "e", 1);
1158 while (isdigit (**mangled
))
1160 string_appendn (s
, *mangled
, 1);
1165 else if (is_pointer
)
1167 int symbol_len
= consume_count (mangled
);
1168 if (symbol_len
== 0)
1170 if (symbol_len
== 0)
1171 string_appendn (s
, "0", 1);
1174 char *p
= xmalloc (symbol_len
+ 1), *q
;
1175 strncpy (p
, *mangled
, symbol_len
);
1176 p
[symbol_len
] = '\0';
1177 q
= cplus_demangle (p
, work
->options
);
1178 string_appendn (s
, "&", 1);
1181 string_append (s
, q
);
1185 string_append (s
, p
);
1188 *mangled
+= symbol_len
;
1195 demangle_template (work
, mangled
, tname
, trawname
, is_type
)
1196 struct work_stuff
*work
;
1197 const char **mangled
;
1207 int is_java_array
= 0;
1214 /* get template name */
1215 if ((r
= consume_count (mangled
)) == 0 || strlen (*mangled
) < r
)
1220 string_appendn (trawname
, *mangled
, r
);
1221 is_java_array
= (work
-> options
& DMGL_JAVA
)
1222 && strncmp (*mangled
, "JArray1Z", 8) == 0;
1223 if (! is_java_array
)
1225 string_appendn (tname
, *mangled
, r
);
1230 string_append (tname
, "<");
1231 /* get size of template parameter list */
1232 if (!get_count (mangled
, &r
))
1238 /* Create an array for saving the template argument values. */
1239 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
1240 work
->ntmpl_args
= r
;
1241 for (i
= 0; i
< r
; i
++)
1242 work
->tmpl_argvec
[i
] = 0;
1244 for (i
= 0; i
< r
; i
++)
1248 string_append (tname
, ", ");
1250 /* Z for type parameters */
1251 if (**mangled
== 'Z')
1254 /* temp is initialized in do_type */
1255 success
= do_type (work
, mangled
, &temp
);
1258 string_appends (tname
, &temp
);
1262 /* Save the template argument. */
1263 int len
= temp
.p
- temp
.b
;
1264 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1265 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
1266 work
->tmpl_argvec
[i
][len
] = '\0';
1269 string_delete(&temp
);
1280 /* otherwise, value parameter */
1282 /* temp is initialized in do_type */
1283 success
= do_type (work
, mangled
, &temp
);
1287 string_appends (s, &temp);
1290 string_delete(&temp
);
1296 string_append (s, "=");
1307 success
= demangle_template_value_parm (work
, mangled
, s
);
1319 int len
= s
->p
- s
->b
;
1320 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1321 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
1322 work
->tmpl_argvec
[i
][len
] = '\0';
1324 string_appends (tname
, s
);
1332 string_append (tname
, "[]");
1336 if (tname
->p
[-1] == '>')
1337 string_append (tname
, " ");
1338 string_append (tname
, ">");
1342 if (work -> static_type)
1344 string_append (declp, *mangled + 1);
1345 *mangled += strlen (*mangled);
1350 success = demangle_args (work, mangled, declp);
1358 arm_pt (work
, mangled
, n
, anchor
, args
)
1359 struct work_stuff
*work
;
1360 const char *mangled
;
1362 const char **anchor
, **args
;
1365 if (ARM_DEMANGLING
&& (*anchor
= mystrstr (mangled
, "__pt__")))
1368 *args
= *anchor
+ 6;
1369 len
= consume_count (args
);
1370 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1380 demangle_arm_pt (work
, mangled
, n
, declp
)
1381 struct work_stuff
*work
;
1382 const char **mangled
;
1388 const char *e
= *mangled
+ n
;
1391 if (arm_pt (work
, *mangled
, n
, &p
, &args
))
1395 string_appendn (declp
, *mangled
, p
- *mangled
);
1396 string_append (declp
, "<");
1397 /* should do error checking here */
1399 string_clear (&arg
);
1400 do_type (work
, &args
, &arg
);
1401 string_appends (declp
, &arg
);
1402 string_append (declp
, ",");
1404 string_delete (&arg
);
1406 string_append (declp
, ">");
1410 string_appendn (declp
, *mangled
, n
);
1416 demangle_class_name (work
, mangled
, declp
)
1417 struct work_stuff
*work
;
1418 const char **mangled
;
1424 n
= consume_count (mangled
);
1425 if (strlen (*mangled
) >= n
)
1427 demangle_arm_pt (work
, mangled
, n
, declp
);
1438 demangle_class -- demangle a mangled class sequence
1443 demangle_class (struct work_stuff *work, const char **mangled,
1448 DECLP points to the buffer into which demangling is being done.
1450 *MANGLED points to the current token to be demangled. On input,
1451 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1452 On exit, it points to the next token after the mangled class on
1453 success, or the first unconsumed token on failure.
1455 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1456 we are demangling a constructor or destructor. In this case
1457 we prepend "class::class" or "class::~class" to DECLP.
1459 Otherwise, we prepend "class::" to the current DECLP.
1461 Reset the constructor/destructor flags once they have been
1462 "consumed". This allows demangle_class to be called later during
1463 the same demangling, to do normal class demangling.
1465 Returns 1 if demangling is successful, 0 otherwise.
1470 demangle_class (work
, mangled
, declp
)
1471 struct work_stuff
*work
;
1472 const char **mangled
;
1478 string_init (&class_name
);
1479 if (demangle_class_name (work
, mangled
, &class_name
))
1481 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1483 string_prepends (declp
, &class_name
);
1484 if (work
-> destructor
& 1)
1486 string_prepend (declp
, "~");
1487 work
-> destructor
-= 1;
1491 work
-> constructor
-= 1;
1494 string_prepend (declp
, (work
-> options
& DMGL_JAVA
) ? "." : "::");
1495 string_prepends (declp
, &class_name
);
1498 string_delete (&class_name
);
1506 demangle_prefix -- consume the mangled name prefix and find signature
1511 demangle_prefix (struct work_stuff *work, const char **mangled,
1516 Consume and demangle the prefix of the mangled name.
1518 DECLP points to the string buffer into which demangled output is
1519 placed. On entry, the buffer is empty. On exit it contains
1520 the root function name, the demangled operator name, or in some
1521 special cases either nothing or the completely demangled result.
1523 MANGLED points to the current pointer into the mangled name. As each
1524 token of the mangled name is consumed, it is updated. Upon entry
1525 the current mangled name pointer points to the first character of
1526 the mangled name. Upon exit, it should point to the first character
1527 of the signature if demangling was successful, or to the first
1528 unconsumed character if demangling of the prefix was unsuccessful.
1530 Returns 1 on success, 0 otherwise.
1534 demangle_prefix (work
, mangled
, declp
)
1535 struct work_stuff
*work
;
1536 const char **mangled
;
1543 if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
1545 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
1546 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
1548 if ((*mangled
)[9] == 'D')
1550 /* it's a GNU global destructor to be executed at program exit */
1552 work
->destructor
= 2;
1553 if (gnu_special (work
, mangled
, declp
))
1556 else if ((*mangled
)[9] == 'I')
1558 /* it's a GNU global constructor to be executed at program init */
1560 work
->constructor
= 2;
1561 if (gnu_special (work
, mangled
, declp
))
1566 else if (ARM_DEMANGLING
&& strncmp(*mangled
, "__std__", 7) == 0)
1568 /* it's a ARM global destructor to be executed at program exit */
1570 work
->destructor
= 2;
1572 else if (ARM_DEMANGLING
&& strncmp(*mangled
, "__sti__", 7) == 0)
1574 /* it's a ARM global constructor to be executed at program initial */
1576 work
->constructor
= 2;
1579 /* This block of code is a reduction in strength time optimization
1581 scan = mystrstr (*mangled, "__"); */
1587 scan
= strchr (scan
, '_');
1588 } while (scan
!= NULL
&& *++scan
!= '_');
1590 if (scan
!= NULL
) --scan
;
1595 /* We found a sequence of two or more '_', ensure that we start at
1596 the last pair in the sequence. */
1597 i
= strspn (scan
, "_");
1608 else if (work
-> static_type
)
1610 if (!isdigit (scan
[0]) && (scan
[0] != 't'))
1615 else if ((scan
== *mangled
)
1616 && (isdigit (scan
[2]) || (scan
[2] == 'Q') || (scan
[2] == 't')
1617 || (scan
[2] == 'H')))
1619 /* The ARM says nothing about the mangling of local variables.
1620 But cfront mangles local variables by prepending __<nesting_level>
1621 to them. As an extension to ARM demangling we handle this case. */
1622 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
) && isdigit (scan
[2]))
1624 *mangled
= scan
+ 2;
1625 consume_count (mangled
);
1626 string_append (declp
, *mangled
);
1627 *mangled
+= strlen (*mangled
);
1632 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1633 names like __Q2_3foo3bar for nested type names. So don't accept
1634 this style of constructor for cfront demangling. A GNU
1635 style member-template constructor starts with 'H'. */
1636 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
))
1637 work
-> constructor
+= 1;
1638 *mangled
= scan
+ 2;
1641 else if ((scan
== *mangled
) && !isdigit (scan
[2]) && (scan
[2] != 't'))
1643 /* Mangled name starts with "__". Skip over any leading '_' characters,
1644 then find the next "__" that separates the prefix from the signature.
1646 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
)
1647 || (arm_special (work
, mangled
, declp
) == 0))
1649 while (*scan
== '_')
1653 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
1655 /* No separator (I.E. "__not_mangled"), or empty signature
1656 (I.E. "__not_mangled_either__") */
1661 demangle_function_name (work
, mangled
, declp
, scan
);
1665 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
1667 /* Cfront-style parameterized type. Handled later as a signature. */
1671 demangle_arm_pt (work
, mangled
, strlen (*mangled
), declp
);
1673 else if (*(scan
+ 2) != '\0')
1675 /* Mangled name does not start with "__" but does have one somewhere
1676 in there with non empty stuff after it. Looks like a global
1678 demangle_function_name (work
, mangled
, declp
, scan
);
1682 /* Doesn't look like a mangled name */
1686 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
1688 string_append (declp
, *mangled
);
1689 *mangled
+= strlen (*mangled
);
1699 gnu_special -- special handling of gnu mangled strings
1704 gnu_special (struct work_stuff *work, const char **mangled,
1710 Process some special GNU style mangling forms that don't fit
1711 the normal pattern. For example:
1713 _$_3foo (destructor for class foo)
1714 _vt$foo (foo virtual table)
1715 _vt$foo$bar (foo::bar virtual table)
1716 __vt_foo (foo virtual table, new style with thunks)
1717 _3foo$varname (static data member)
1718 _Q22rs2tu$vw (static data member)
1719 __t6vector1Zii (constructor with template)
1720 __thunk_4__$_7ostream (virtual function thunk)
1724 gnu_special (work
, mangled
, declp
)
1725 struct work_stuff
*work
;
1726 const char **mangled
;
1733 if ((*mangled
)[0] == '_'
1734 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
1735 && (*mangled
)[2] == '_')
1737 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1739 work
-> destructor
+= 1;
1741 else if ((*mangled
)[0] == '_'
1742 && (((*mangled
)[1] == '_'
1743 && (*mangled
)[2] == 'v'
1744 && (*mangled
)[3] == 't'
1745 && (*mangled
)[4] == '_')
1746 || ((*mangled
)[1] == 'v'
1747 && (*mangled
)[2] == 't'
1748 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
1750 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1751 and create the decl. Note that we consume the entire mangled
1752 input string, which means that demangle_signature has no work
1754 if ((*mangled
)[2] == 'v')
1755 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
1757 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1758 while (**mangled
!= '\0')
1760 p
= strpbrk (*mangled
, cplus_markers
);
1764 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
1767 success
= demangle_template (work
, mangled
, declp
, 0, 1);
1770 if (isdigit(*mangled
[0]))
1772 n
= consume_count(mangled
);
1773 /* We may be seeing a too-large size, or else a
1774 ".<digits>" indicating a static local symbol. In
1775 any case, declare victory and move on; *don't* try
1776 to use n to allocate. */
1777 if (n
>= strlen (*mangled
))
1785 n
= strcspn (*mangled
, cplus_markers
);
1787 string_appendn (declp
, *mangled
, n
);
1791 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
1795 string_append (declp
,
1796 (work
-> options
& DMGL_JAVA
) ? "." : "::");
1807 string_append (declp
, " virtual table");
1809 else if ((*mangled
)[0] == '_'
1810 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
1811 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
1813 /* static data member, "_3foo$varname" for example */
1818 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
1821 success
= demangle_template (work
, mangled
, declp
, 0, 1);
1824 n
= consume_count (mangled
);
1825 string_appendn (declp
, *mangled
, n
);
1828 if (success
&& (p
== *mangled
))
1830 /* Consumed everything up to the cplus_marker, append the
1833 string_append (declp
, (work
-> options
& DMGL_JAVA
) ? "." : "::");
1834 n
= strlen (*mangled
);
1835 string_appendn (declp
, *mangled
, n
);
1843 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
1845 int delta
= ((*mangled
) += 8, consume_count (mangled
));
1846 char *method
= cplus_demangle (++*mangled
, work
->options
);
1850 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
1851 string_append (declp
, buf
);
1852 string_append (declp
, method
);
1854 n
= strlen (*mangled
);
1862 else if (strncmp (*mangled
, "__t", 3) == 0
1863 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
1865 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
1870 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
1873 success
= demangle_template (work
, mangled
, declp
, 0, 1);
1876 success
= demangle_fund_type (work
, mangled
, declp
);
1879 if (success
&& **mangled
!= '\0')
1882 string_append (declp
, p
);
1895 arm_special -- special handling of ARM/lucid mangled strings
1900 arm_special (struct work_stuff *work, const char **mangled,
1906 Process some special ARM style mangling forms that don't fit
1907 the normal pattern. For example:
1909 __vtbl__3foo (foo virtual table)
1910 __vtbl__3foo__3bar (bar::foo virtual table)
1915 arm_special (work
, mangled
, declp
)
1916 struct work_stuff
*work
;
1917 const char **mangled
;
1924 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
1926 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1927 and create the decl. Note that we consume the entire mangled
1928 input string, which means that demangle_signature has no work
1930 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
1931 while (*scan
!= '\0') /* first check it can be demangled */
1933 n
= consume_count (&scan
);
1936 return (0); /* no good */
1939 if (scan
[0] == '_' && scan
[1] == '_')
1944 (*mangled
) += ARM_VTABLE_STRLEN
;
1945 while (**mangled
!= '\0')
1947 n
= consume_count (mangled
);
1948 string_prependn (declp
, *mangled
, n
);
1950 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
1952 string_prepend (declp
, "::");
1956 string_append (declp
, " virtual table");
1969 demangle_qualified -- demangle 'Q' qualified name strings
1974 demangle_qualified (struct work_stuff *, const char *mangled,
1975 string *result, int isfuncname, int append);
1979 Demangle a qualified name, such as "Q25Outer5Inner" which is
1980 the mangled form of "Outer::Inner". The demangled output is
1981 prepended or appended to the result string according to the
1982 state of the append flag.
1984 If isfuncname is nonzero, then the qualified name we are building
1985 is going to be used as a member function name, so if it is a
1986 constructor or destructor function, append an appropriate
1987 constructor or destructor name. I.E. for the above example,
1988 the result for use as a constructor is "Outer::Inner::Inner"
1989 and the result for use as a destructor is "Outer::Inner::~Inner".
1993 Numeric conversion is ASCII dependent (FIXME).
1998 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
1999 struct work_stuff
*work
;
2000 const char **mangled
;
2012 string_init (&temp
);
2013 switch ((*mangled
)[1])
2016 /* GNU mangled name with more than 9 classes. The count is preceded
2017 by an underscore (to distinguish it from the <= 9 case) and followed
2018 by an underscore. */
2020 qualifiers
= atoi (p
);
2021 if (!isdigit (*p
) || *p
== '0')
2024 /* Skip the digits. */
2025 while (isdigit (*p
))
2043 /* The count is in a single digit. */
2044 num
[0] = (*mangled
)[1];
2046 qualifiers
= atoi (num
);
2048 /* If there is an underscore after the digit, skip it. This is
2049 said to be for ARM-qualified names, but the ARM makes no
2050 mention of such an underscore. Perhaps cfront uses one. */
2051 if ((*mangled
)[2] == '_')
2066 /* Pick off the names and collect them in the temp buffer in the order
2067 in which they are found, separated by '::'. */
2069 while (qualifiers
-- > 0)
2071 if (*mangled
[0] == '_')
2072 *mangled
= *mangled
+ 1;
2073 if (*mangled
[0] == 't')
2075 success
= demangle_template(work
, mangled
, &temp
, 0, 1);
2076 if (!success
) break;
2078 else if (*mangled
[0] == 'X')
2080 success
= do_type (work
, mangled
, &temp
);
2081 if (!success
) break;
2085 namelength
= consume_count (mangled
);
2086 if (strlen (*mangled
) < namelength
)
2088 /* Simple sanity check failed */
2092 string_appendn (&temp
, *mangled
, namelength
);
2093 *mangled
+= namelength
;
2097 string_append (&temp
, (work
-> options
& DMGL_JAVA
) ? "." : "::");
2101 /* If we are using the result as a function name, we need to append
2102 the appropriate '::' separated constructor or destructor name.
2103 We do this here because this is the most convenient place, where
2104 we already have a pointer to the name and the length of the name. */
2106 if (isfuncname
&& (work
->constructor
& 1 || work
->destructor
& 1))
2108 string_append (&temp
, (work
-> options
& DMGL_JAVA
) ? "." : "::");
2109 if (work
-> destructor
& 1)
2111 string_append (&temp
, "~");
2113 string_appendn (&temp
, (*mangled
) - namelength
, namelength
);
2116 /* Now either prepend the temp buffer to the result, or append it,
2117 depending upon the state of the append flag. */
2121 string_appends (result
, &temp
);
2125 if (!STRING_EMPTY (result
))
2127 string_append (&temp
, (work
-> options
& DMGL_JAVA
) ? "." : "::");
2129 string_prepends (result
, &temp
);
2132 string_delete (&temp
);
2140 get_count -- convert an ascii count to integer, consuming tokens
2145 get_count (const char **type, int *count)
2149 Return 0 if no conversion is performed, 1 if a string is converted.
2153 get_count (type
, count
)
2160 if (!isdigit (**type
))
2166 *count
= **type
- '0';
2168 if (isdigit (**type
))
2178 while (isdigit (*p
));
2189 /* result will be initialised here; it will be freed on failure */
2192 do_type (work
, mangled
, result
)
2193 struct work_stuff
*work
;
2194 const char **mangled
;
2201 const char *remembered_type
;
2205 string_init (&decl
);
2206 string_init (result
);
2210 while (success
&& !done
)
2216 /* A pointer type */
2220 if (! (work
-> options
& DMGL_JAVA
))
2221 string_prepend (&decl
, "*");
2224 /* A reference type */
2227 string_prepend (&decl
, "&");
2233 const char *p
= ++(*mangled
);
2235 string_prepend (&decl
, "(");
2236 string_append (&decl
, ")[");
2237 /* Copy anything up until the next underscore (the size of the
2239 while (**mangled
&& **mangled
!= '_')
2241 if (**mangled
== '_')
2243 string_appendn (&decl
, p
, *mangled
- p
);
2244 string_append (&decl
, "]");
2252 /* A back reference to a previously seen type */
2255 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
2261 remembered_type
= work
-> typevec
[n
];
2262 mangled
= &remembered_type
;
2269 if (!STRING_EMPTY (&decl
) && decl
.b
[0] == '*')
2271 string_prepend (&decl
, "(");
2272 string_append (&decl
, ")");
2274 /* After picking off the function args, we expect to either find the
2275 function return type (preceded by an '_') or the end of the
2277 if (!demangle_args (work
, mangled
, &decl
)
2278 || (**mangled
!= '_' && **mangled
!= '\0'))
2282 if (success
&& (**mangled
== '_'))
2294 member
= **mangled
== 'M';
2296 if (!isdigit (**mangled
) && **mangled
!= 't')
2302 string_append (&decl
, ")");
2303 string_prepend (&decl
, (work
-> options
& DMGL_JAVA
) ? "." : "::");
2304 if (isdigit (**mangled
))
2306 n
= consume_count (mangled
);
2307 if (strlen (*mangled
) < n
)
2312 string_prependn (&decl
, *mangled
, n
);
2318 string_init (&temp
);
2319 success
= demangle_template (work
, mangled
, &temp
, NULL
, 1);
2322 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
2323 string_clear (&temp
);
2328 string_prepend (&decl
, "(");
2331 if (**mangled
== 'C')
2336 if (**mangled
== 'V')
2341 if (*(*mangled
)++ != 'F')
2347 if ((member
&& !demangle_args (work
, mangled
, &decl
))
2348 || **mangled
!= '_')
2354 if (! PRINT_ANSI_QUALIFIERS
)
2360 APPEND_BLANK (&decl
);
2361 string_append (&decl
, "const");
2365 APPEND_BLANK (&decl
);
2366 string_append (&decl
, "volatile");
2377 if ((*mangled)[1] == 'P')
2380 if (PRINT_ANSI_QUALIFIERS
)
2382 if (!STRING_EMPTY (&decl
))
2384 string_prepend (&decl
, " ");
2386 string_prepend (&decl
, "const");
2402 /* A qualified name, such as "Outer::Inner". */
2404 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
2409 /* A template parm. We substitute the corresponding argument. */
2415 idx
= consume_count_with_underscores (mangled
);
2418 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2419 || consume_count_with_underscores (mangled
) == -1)
2425 if (work
->tmpl_argvec
)
2426 string_append (result
, work
->tmpl_argvec
[idx
]);
2430 sprintf(buf
, "T%d", idx
);
2431 string_append (result
, buf
);
2439 success
= demangle_fund_type (work
, mangled
, result
);
2445 if (!STRING_EMPTY (&decl
))
2447 string_append (result
, " ");
2448 string_appends (result
, &decl
);
2453 string_delete (result
);
2455 string_delete (&decl
);
2459 /* Given a pointer to a type string that represents a fundamental type
2460 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2461 string in which the demangled output is being built in RESULT, and
2462 the WORK structure, decode the types and add them to the result.
2467 "Sl" => "signed long"
2468 "CUs" => "const unsigned short"
2473 demangle_fund_type (work
, mangled
, result
)
2474 struct work_stuff
*work
;
2475 const char **mangled
;
2481 /* First pick off any type qualifiers. There can be more than one. */
2489 if (PRINT_ANSI_QUALIFIERS
)
2491 APPEND_BLANK (result
);
2492 string_append (result
, "const");
2497 APPEND_BLANK (result
);
2498 string_append (result
, "unsigned");
2500 case 'S': /* signed char only */
2502 APPEND_BLANK (result
);
2503 string_append (result
, "signed");
2507 if (PRINT_ANSI_QUALIFIERS
)
2509 APPEND_BLANK (result
);
2510 string_append (result
, "volatile");
2515 APPEND_BLANK (result
);
2516 string_append (result
, "__complex");
2524 /* Now pick off the fundamental type. There can be only one. */
2533 APPEND_BLANK (result
);
2534 string_append (result
, "void");
2538 APPEND_BLANK (result
);
2539 string_append (result
, "long long");
2543 APPEND_BLANK (result
);
2544 string_append (result
, "long");
2548 APPEND_BLANK (result
);
2549 string_append (result
, "int");
2553 APPEND_BLANK (result
);
2554 string_append (result
, "short");
2558 APPEND_BLANK (result
);
2559 string_append (result
, "bool");
2563 APPEND_BLANK (result
);
2564 string_append (result
, "char");
2568 APPEND_BLANK (result
);
2569 string_append (result
, "wchar_t");
2573 APPEND_BLANK (result
);
2574 string_append (result
, "long double");
2578 APPEND_BLANK (result
);
2579 string_append (result
, "double");
2583 APPEND_BLANK (result
);
2584 string_append (result
, "float");
2588 if (!isdigit (**mangled
))
2594 /* An explicit type, such as "6mytype" or "7integer" */
2605 APPEND_BLANK (result
);
2606 if (!demangle_class_name (work
, mangled
, result
)) {
2612 success
= demangle_template(work
,mangled
, result
, 0, 1);
2622 /* `result' will be initialized in do_type; it will be freed on failure */
2625 do_arg (work
, mangled
, result
)
2626 struct work_stuff
*work
;
2627 const char **mangled
;
2630 const char *start
= *mangled
;
2632 if (!do_type (work
, mangled
, result
))
2638 remember_type (work
, start
, *mangled
- start
);
2644 remember_type (work
, start
, len
)
2645 struct work_stuff
*work
;
2651 if (work
-> ntypes
>= work
-> typevec_size
)
2653 if (work
-> typevec_size
== 0)
2655 work
-> typevec_size
= 3;
2657 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
2661 work
-> typevec_size
*= 2;
2663 = (char **) xrealloc ((char *)work
-> typevec
,
2664 sizeof (char *) * work
-> typevec_size
);
2667 tem
= xmalloc (len
+ 1);
2668 memcpy (tem
, start
, len
);
2670 work
-> typevec
[work
-> ntypes
++] = tem
;
2673 /* Forget the remembered types, but not the type vector itself. */
2677 struct work_stuff
*work
;
2681 while (work
-> ntypes
> 0)
2683 i
= --(work
-> ntypes
);
2684 if (work
-> typevec
[i
] != NULL
)
2686 free (work
-> typevec
[i
]);
2687 work
-> typevec
[i
] = NULL
;
2692 /* Process the argument list part of the signature, after any class spec
2693 has been consumed, as well as the first 'F' character (if any). For
2696 "__als__3fooRT0" => process "RT0"
2697 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2699 DECLP must be already initialised, usually non-empty. It won't be freed
2702 Note that g++ differs significantly from ARM and lucid style mangling
2703 with regards to references to previously seen types. For example, given
2704 the source fragment:
2708 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2711 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2712 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2714 g++ produces the names:
2719 while lcc (and presumably other ARM style compilers as well) produces:
2721 foo__FiR3fooT1T2T1T2
2722 __ct__3fooFiR3fooT1T2T1T2
2724 Note that g++ bases it's type numbers starting at zero and counts all
2725 previously seen types, while lucid/ARM bases it's type numbers starting
2726 at one and only considers types after it has seen the 'F' character
2727 indicating the start of the function args. For lucid/ARM style, we
2728 account for this difference by discarding any previously seen types when
2729 we see the 'F' character, and subtracting one from the type number
2735 demangle_args (work
, mangled
, declp
)
2736 struct work_stuff
*work
;
2737 const char **mangled
;
2747 if (PRINT_ARG_TYPES
)
2749 string_append (declp
, "(");
2750 if (**mangled
== '\0')
2752 string_append (declp
, "void");
2756 while (**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
2758 if ((**mangled
== 'N') || (**mangled
== 'T'))
2760 temptype
= *(*mangled
)++;
2762 if (temptype
== 'N')
2764 if (!get_count (mangled
, &r
))
2773 if (ARM_DEMANGLING
&& work
-> ntypes
>= 10)
2775 /* If we have 10 or more types we might have more than a 1 digit
2776 index so we'll have to consume the whole count here. This
2777 will lose if the next thing is a type name preceded by a
2778 count but it's impossible to demangle that case properly
2779 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2780 Pc, ...)" or "(..., type12, char *, ...)" */
2781 if ((t
= consume_count(mangled
)) == 0)
2788 if (!get_count (mangled
, &t
))
2793 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
)
2797 /* Validate the type index. Protect against illegal indices from
2798 malformed type strings. */
2799 if ((t
< 0) || (t
>= work
-> ntypes
))
2805 tem
= work
-> typevec
[t
];
2806 if (need_comma
&& PRINT_ARG_TYPES
)
2808 string_append (declp
, ", ");
2810 if (!do_arg (work
, &tem
, &arg
))
2814 if (PRINT_ARG_TYPES
)
2816 string_appends (declp
, &arg
);
2818 string_delete (&arg
);
2824 if (need_comma
& PRINT_ARG_TYPES
)
2826 string_append (declp
, ", ");
2828 if (!do_arg (work
, mangled
, &arg
))
2832 if (PRINT_ARG_TYPES
)
2834 string_appends (declp
, &arg
);
2836 string_delete (&arg
);
2841 if (**mangled
== 'e')
2844 if (PRINT_ARG_TYPES
)
2848 string_append (declp
, ",");
2850 string_append (declp
, "...");
2854 if (PRINT_ARG_TYPES
)
2856 string_append (declp
, ")");
2862 demangle_function_name (work
, mangled
, declp
, scan
)
2863 struct work_stuff
*work
;
2864 const char **mangled
;
2873 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
2874 string_need (declp
, 1);
2875 *(declp
-> p
) = '\0';
2877 /* Consume the function name, including the "__" separating the name
2878 from the signature. We are guaranteed that SCAN points to the
2881 (*mangled
) = scan
+ 2;
2883 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
)
2886 /* See if we have an ARM style constructor or destructor operator.
2887 If so, then just record it, clear the decl, and return.
2888 We can't build the actual constructor/destructor decl until later,
2889 when we recover the class name from the signature. */
2891 if (strcmp (declp
-> b
, "__ct") == 0)
2893 work
-> constructor
+= 1;
2894 string_clear (declp
);
2897 else if (strcmp (declp
-> b
, "__dt") == 0)
2899 work
-> destructor
+= 1;
2900 string_clear (declp
);
2905 if (declp
->p
- declp
->b
>= 3
2906 && declp
->b
[0] == 'o'
2907 && declp
->b
[1] == 'p'
2908 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
2910 /* see if it's an assignment expression */
2911 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
2912 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
2914 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
2916 len
= declp
->p
- declp
->b
- 10;
2917 if (strlen (optable
[i
].in
) == len
2918 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
2920 string_clear (declp
);
2921 string_append (declp
, "operator");
2922 string_append (declp
, optable
[i
].out
);
2923 string_append (declp
, "=");
2930 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
2932 int len
= declp
->p
- declp
->b
- 3;
2933 if (strlen (optable
[i
].in
) == len
2934 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
2936 string_clear (declp
);
2937 string_append (declp
, "operator");
2938 string_append (declp
, optable
[i
].out
);
2944 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
2945 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
2947 /* type conversion operator */
2949 if (do_type (work
, &tem
, &type
))
2951 string_clear (declp
);
2952 string_append (declp
, "operator ");
2953 string_appends (declp
, &type
);
2954 string_delete (&type
);
2957 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
2958 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
2961 /* type conversion operator. */
2963 if (do_type (work
, &tem
, &type
))
2965 string_clear (declp
);
2966 string_append (declp
, "operator ");
2967 string_appends (declp
, &type
);
2968 string_delete (&type
);
2971 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
2972 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
2973 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
2975 if (declp
->b
[4] == '\0')
2978 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
2980 if (strlen (optable
[i
].in
) == 2
2981 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
2983 string_clear (declp
);
2984 string_append (declp
, "operator");
2985 string_append (declp
, optable
[i
].out
);
2992 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
2995 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
2997 if (strlen (optable
[i
].in
) == 3
2998 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
3000 string_clear (declp
);
3001 string_append (declp
, "operator");
3002 string_append (declp
, optable
[i
].out
);
3011 /* a mini string-handling package */
3026 s
->p
= s
->b
= xmalloc (n
);
3029 else if (s
->e
- s
->p
< n
)
3034 s
->b
= xrealloc (s
->b
, n
);
3047 s
->b
= s
->e
= s
->p
= NULL
;
3055 s
->b
= s
->p
= s
->e
= NULL
;
3071 return (s
->b
== s
->p
);
3077 string_append (p
, s
)
3082 if (s
== NULL
|| *s
== '\0')
3086 memcpy (p
->p
, s
, n
);
3091 string_appends (p
, s
)
3100 memcpy (p
->p
, s
->b
, n
);
3106 string_appendn (p
, s
, n
)
3114 memcpy (p
->p
, s
, n
);
3120 string_prepend (p
, s
)
3124 if (s
!= NULL
&& *s
!= '\0')
3126 string_prependn (p
, s
, strlen (s
));
3131 string_prepends (p
, s
)
3136 string_prependn (p
, s
->b
, s
->p
- s
->b
);
3141 string_prependn (p
, s
, n
)
3151 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
3155 memcpy (p
->b
, s
, n
);
3160 /* To generate a standalone demangler program for testing purposes,
3161 just compile and link this file with -DMAIN and libiberty.a. When
3162 run, it demangles each command line arg, or each stdin string, and
3163 prints the result on stdout. */
3169 static char *program_name
;
3170 static char *program_version
= VERSION
;
3171 static int flags
= DMGL_PARAMS
| DMGL_ANSI
;
3173 static void demangle_it
PARAMS ((char *));
3174 static void usage
PARAMS ((FILE *, int));
3175 static void fatal
PARAMS ((char *));
3178 demangle_it (mangled_name
)
3183 result
= cplus_demangle (mangled_name
, flags
);
3186 printf ("%s\n", mangled_name
);
3190 printf ("%s\n", result
);
3196 usage (stream
, status
)
3201 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3202 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3203 [--help] [--version] [arg...]\n",
3208 #define MBUF_SIZE 512
3209 char mbuffer
[MBUF_SIZE
];
3211 /* Defined in the automatically-generated underscore.c. */
3212 extern int prepends_underscore
;
3214 int strip_underscore
= 0;
3216 static struct option long_options
[] = {
3217 {"strip-underscores", no_argument
, 0, '_'},
3218 {"format", required_argument
, 0, 's'},
3219 {"help", no_argument
, 0, 'h'},
3220 {"java", no_argument
, 0, 'j'},
3221 {"no-strip-underscores", no_argument
, 0, 'n'},
3222 {"version", no_argument
, 0, 'v'},
3223 {0, no_argument
, 0, 0}
3234 program_name
= argv
[0];
3236 strip_underscore
= prepends_underscore
;
3238 while ((c
= getopt_long (argc
, argv
, "_ns:j", long_options
, (int *) 0)) != EOF
)
3248 strip_underscore
= 0;
3251 printf ("GNU %s version %s\n", program_name
, program_version
);
3254 strip_underscore
= 1;
3260 if (strcmp (optarg
, "gnu") == 0)
3262 current_demangling_style
= gnu_demangling
;
3264 else if (strcmp (optarg
, "lucid") == 0)
3266 current_demangling_style
= lucid_demangling
;
3268 else if (strcmp (optarg
, "arm") == 0)
3270 current_demangling_style
= arm_demangling
;
3274 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
3275 program_name
, optarg
);
3284 for ( ; optind
< argc
; optind
++)
3286 demangle_it (argv
[optind
]);
3295 /* Try to read a label. */
3296 while (c
!= EOF
&& (isalnum(c
) || c
== '_' || c
== '$' || c
== '.'))
3298 if (i
>= MBUF_SIZE
-1)
3307 if (mbuffer
[0] == '.')
3309 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
3317 result
= cplus_demangle (mbuffer
+ skip_first
, flags
);
3320 if (mbuffer
[0] == '.')
3322 fputs (result
, stdout
);
3326 fputs (mbuffer
, stdout
);
3343 fprintf (stderr
, "%s: %s\n", program_name
, str
);
3354 register char *value
= (char *) malloc (size
);
3356 fatal ("virtual memory exhausted");
3361 xrealloc (ptr
, size
)
3365 register char *value
= (char *) realloc (ptr
, size
);
3367 fatal ("virtual memory exhausted");