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 */
107 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
108 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
110 static const struct optable
116 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
117 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
118 {"new", " new", 0}, /* old (1.91, and 1.x) */
119 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
120 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
121 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
122 {"as", "=", DMGL_ANSI
}, /* ansi */
123 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
124 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
125 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
126 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
127 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
128 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
129 {"plus", "+", 0}, /* old */
130 {"pl", "+", DMGL_ANSI
}, /* ansi */
131 {"apl", "+=", DMGL_ANSI
}, /* ansi */
132 {"minus", "-", 0}, /* old */
133 {"mi", "-", DMGL_ANSI
}, /* ansi */
134 {"ami", "-=", DMGL_ANSI
}, /* ansi */
135 {"mult", "*", 0}, /* old */
136 {"ml", "*", DMGL_ANSI
}, /* ansi */
137 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
138 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
139 {"convert", "+", 0}, /* old (unary +) */
140 {"negate", "-", 0}, /* old (unary -) */
141 {"trunc_mod", "%", 0}, /* old */
142 {"md", "%", DMGL_ANSI
}, /* ansi */
143 {"amd", "%=", DMGL_ANSI
}, /* ansi */
144 {"trunc_div", "/", 0}, /* old */
145 {"dv", "/", DMGL_ANSI
}, /* ansi */
146 {"adv", "/=", DMGL_ANSI
}, /* ansi */
147 {"truth_andif", "&&", 0}, /* old */
148 {"aa", "&&", DMGL_ANSI
}, /* ansi */
149 {"truth_orif", "||", 0}, /* old */
150 {"oo", "||", DMGL_ANSI
}, /* ansi */
151 {"truth_not", "!", 0}, /* old */
152 {"nt", "!", DMGL_ANSI
}, /* ansi */
153 {"postincrement","++", 0}, /* old */
154 {"pp", "++", DMGL_ANSI
}, /* ansi */
155 {"postdecrement","--", 0}, /* old */
156 {"mm", "--", DMGL_ANSI
}, /* ansi */
157 {"bit_ior", "|", 0}, /* old */
158 {"or", "|", DMGL_ANSI
}, /* ansi */
159 {"aor", "|=", DMGL_ANSI
}, /* ansi */
160 {"bit_xor", "^", 0}, /* old */
161 {"er", "^", DMGL_ANSI
}, /* ansi */
162 {"aer", "^=", DMGL_ANSI
}, /* ansi */
163 {"bit_and", "&", 0}, /* old */
164 {"ad", "&", DMGL_ANSI
}, /* ansi */
165 {"aad", "&=", DMGL_ANSI
}, /* ansi */
166 {"bit_not", "~", 0}, /* old */
167 {"co", "~", DMGL_ANSI
}, /* ansi */
168 {"call", "()", 0}, /* old */
169 {"cl", "()", DMGL_ANSI
}, /* ansi */
170 {"alshift", "<<", 0}, /* old */
171 {"ls", "<<", DMGL_ANSI
}, /* ansi */
172 {"als", "<<=", DMGL_ANSI
}, /* ansi */
173 {"arshift", ">>", 0}, /* old */
174 {"rs", ">>", DMGL_ANSI
}, /* ansi */
175 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
176 {"component", "->", 0}, /* old */
177 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
178 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
179 {"indirect", "*", 0}, /* old */
180 {"method_call", "->()", 0}, /* old */
181 {"addr", "&", 0}, /* old (unary &) */
182 {"array", "[]", 0}, /* old */
183 {"vc", "[]", DMGL_ANSI
}, /* ansi */
184 {"compound", ", ", 0}, /* old */
185 {"cm", ", ", DMGL_ANSI
}, /* ansi */
186 {"cond", "?:", 0}, /* old */
187 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
188 {"max", ">?", 0}, /* old */
189 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
190 {"min", "<?", 0}, /* old */
191 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
192 {"nop", "", 0}, /* old (for operator=) */
193 {"rm", "->*", DMGL_ANSI
} /* ansi */
197 typedef struct string
/* Beware: these aren't required to be */
198 { /* '\0' terminated. */
199 char *b
; /* pointer to start of string */
200 char *p
; /* pointer after last character */
201 char *e
; /* pointer after end of allocated space */
204 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
205 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
206 string_prepend(str, " ");}
207 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
208 string_append(str, " ");}
210 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
211 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
213 /* Prototypes for local functions */
216 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
220 demangle_method_args
PARAMS ((struct work_stuff
*work
, const char **, string
*));
224 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*,
228 arm_pt
PARAMS ((struct work_stuff
*, const char *, int, const char **,
232 demangle_arm_pt
PARAMS ((struct work_stuff
*, const char **, int, string
*));
235 demangle_class_name
PARAMS ((struct work_stuff
*, const char **, string
*));
238 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
242 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
245 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
248 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
251 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
254 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
257 arm_special
PARAMS ((struct work_stuff
*, const char **, string
*));
260 string_need
PARAMS ((string
*, int));
263 string_delete
PARAMS ((string
*));
266 string_init
PARAMS ((string
*));
269 string_clear
PARAMS ((string
*));
273 string_empty
PARAMS ((string
*));
277 string_append
PARAMS ((string
*, const char *));
280 string_appends
PARAMS ((string
*, string
*));
283 string_appendn
PARAMS ((string
*, const char *, int));
286 string_prepend
PARAMS ((string
*, const char *));
289 string_prependn
PARAMS ((string
*, const char *, int));
292 get_count
PARAMS ((const char **, int *));
295 consume_count
PARAMS ((const char **));
298 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
301 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
304 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
307 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
311 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
314 forget_types
PARAMS ((struct work_stuff
*));
317 string_prepends
PARAMS ((string
*, string
*));
319 /* Translate count to integer, consuming tokens in the process.
320 Conversion terminates on the first non-digit character.
321 Trying to consume something that isn't a count results in
322 no consumption of input and a return of 0. */
330 while (isdigit (**type
))
333 count
+= **type
- '0';
340 cplus_demangle_opname (opname
, result
, options
)
345 int len
, i
, len1
, ret
;
347 struct work_stuff work
[1];
350 len
= strlen(opname
);
353 work
->options
= options
;
355 if (opname
[0] == '_' && opname
[1] == '_'
356 && opname
[2] == 'o' && opname
[3] == 'p')
359 /* type conversion operator. */
361 if (do_type (work
, &tem
, &type
))
363 strcat (result
, "operator ");
364 strncat (result
, type
.b
, type
.p
- type
.b
);
365 string_delete (&type
);
369 else if (opname
[0] == '_' && opname
[1] == '_'
370 && opname
[2] >= 'a' && opname
[2] <= 'z'
371 && opname
[3] >= 'a' && opname
[3] <= 'z')
373 if (opname
[4] == '\0')
376 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
378 if (strlen (optable
[i
].in
) == 2
379 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
381 strcat (result
, "operator");
382 strcat (result
, optable
[i
].out
);
390 if (opname
[2] == 'a' && opname
[5] == '\0')
393 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
395 if (strlen (optable
[i
].in
) == 3
396 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
398 strcat (result
, "operator");
399 strcat (result
, optable
[i
].out
);
410 && strchr (cplus_markers
, opname
[2]) != NULL
)
412 /* see if it's an assignment expression */
413 if (len
>= 10 /* op$assign_ */
414 && memcmp (opname
+ 3, "assign_", 7) == 0)
416 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
419 if (strlen (optable
[i
].in
) == len1
420 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
422 strcat (result
, "operator");
423 strcat (result
, optable
[i
].out
);
424 strcat (result
, "=");
432 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
435 if (strlen (optable
[i
].in
) == len1
436 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
438 strcat (result
, "operator");
439 strcat (result
, optable
[i
].out
);
446 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
447 && strchr (cplus_markers
, opname
[4]) != NULL
)
449 /* type conversion operator */
451 if (do_type (work
, &tem
, &type
))
453 strcat (result
, "operator ");
454 strncat (result
, type
.b
, type
.p
- type
.b
);
455 string_delete (&type
);
462 /* Takes operator name as e.g. "++" and returns mangled
463 operator name (e.g. "postincrement_expr"), or NULL if not found.
465 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
466 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
469 cplus_mangle_opname (opname
, options
)
476 len
= strlen (opname
);
477 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
479 if (strlen (optable
[i
].out
) == len
480 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
481 && memcmp (optable
[i
].out
, opname
, len
) == 0)
482 return optable
[i
].in
;
487 /* char *cplus_demangle (const char *mangled, int options)
489 If MANGLED is a mangled function name produced by GNU C++, then
490 a pointer to a malloced string giving a C++ representation
491 of the name will be returned; otherwise NULL will be returned.
492 It is the caller's responsibility to free the string which
495 The OPTIONS arg may contain one or more of the following bits:
497 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
499 DMGL_PARAMS Function parameters are included.
503 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
504 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
505 cplus_demangle ("foo__1Ai", 0) => "A::foo"
507 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
508 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
509 cplus_demangle ("foo__1Afe", 0) => "A::foo"
511 Note that any leading underscores, or other such characters prepended by
512 the compilation system, are presumed to have already been stripped from
516 cplus_demangle (mangled
, options
)
522 struct work_stuff work
[1];
523 char *demangled
= NULL
;
525 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
527 memset ((char *) work
, 0, sizeof (work
));
528 work
-> options
= options
;
529 if ((work
->options
& DMGL_STYLE_MASK
) == 0)
530 work
->options
|= (int)current_demangling_style
& DMGL_STYLE_MASK
;
534 /* First check to see if gnu style demangling is active and if the
535 string to be demangled contains a CPLUS_MARKER. If so, attempt to
536 recognize one of the gnu special forms rather than looking for a
537 standard prefix. In particular, don't worry about whether there
538 is a "__" string in the mangled string. Consider "_$_5__foo" for
541 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
543 success
= gnu_special (work
, &mangled
, &decl
);
547 success
= demangle_prefix (work
, &mangled
, &decl
);
549 if (success
&& (*mangled
!= '\0'))
551 success
= demangle_signature (work
, &mangled
, &decl
);
553 if (work
->constructor
== 2)
555 string_prepend(&decl
, "global constructors keyed to ");
556 work
->constructor
= 0;
558 else if (work
->destructor
== 2)
560 string_prepend(&decl
, "global destructors keyed to ");
561 work
->destructor
= 0;
563 demangled
= mop_up (work
, &decl
, success
);
569 mop_up (work
, declp
, success
)
570 struct work_stuff
*work
;
574 char *demangled
= NULL
;
576 /* Discard the remembered types, if any. */
579 if (work
-> typevec
!= NULL
)
581 free ((char *) work
-> typevec
);
584 /* If demangling was successful, ensure that the demangled string is null
585 terminated and return it. Otherwise, free the demangling decl. */
589 string_delete (declp
);
593 string_appendn (declp
, "", 1);
594 demangled
= declp
-> b
;
603 demangle_signature -- demangle the signature part of a mangled name
608 demangle_signature (struct work_stuff *work, const char **mangled,
613 Consume and demangle the signature portion of the mangled name.
615 DECLP is the string where demangled output is being built. At
616 entry it contains the demangled root name from the mangled name
617 prefix. I.E. either a demangled operator name or the root function
618 name. In some special cases, it may contain nothing.
620 *MANGLED points to the current unconsumed location in the mangled
621 name. As tokens are consumed and demangling is performed, the
622 pointer is updated to continuously point at the next token to
625 Demangling GNU style mangled names is nasty because there is no
626 explicit token that marks the start of the outermost function
630 demangle_signature (work
, mangled
, declp
)
631 struct work_stuff
*work
;
632 const char **mangled
;
638 const char *oldmangled
= NULL
;
642 while (success
&& (**mangled
!= '\0'))
647 oldmangled
= *mangled
;
648 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
651 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
653 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
661 /* Static member function */
662 if (oldmangled
== NULL
)
664 oldmangled
= *mangled
;
667 work
-> static_type
= 1;
671 /* a const member function */
672 if (oldmangled
== NULL
)
674 oldmangled
= *mangled
;
677 work
-> const_type
= 1;
680 case '0': case '1': case '2': case '3': case '4':
681 case '5': case '6': case '7': case '8': case '9':
682 if (oldmangled
== NULL
)
684 oldmangled
= *mangled
;
686 success
= demangle_class (work
, mangled
, declp
);
689 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
691 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
700 /* ARM style demangling includes a specific 'F' character after
701 the class name. For GNU style, it is just implied. So we can
702 safely just consume any 'F' at this point and be compatible
703 with either style. */
709 /* For lucid/ARM style we have to forget any types we might
710 have remembered up to this point, since they were not argument
711 types. GNU style considers all types seen as available for
712 back references. See comment in demangle_args() */
714 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
)
718 success
= demangle_args (work
, mangled
, declp
);
723 string_init(&trawname
);
725 if (oldmangled
== NULL
)
727 oldmangled
= *mangled
;
729 success
= demangle_template (work
, mangled
, &tname
, &trawname
);
732 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
734 string_append(&tname
, "::");
735 string_prepends(declp
, &tname
);
736 if (work
-> destructor
& 1)
738 string_prepend (&trawname
, "~");
739 string_appends (declp
, &trawname
);
740 work
->destructor
-= 1;
742 if ((work
->constructor
& 1) || (work
->destructor
& 1))
744 string_appends (declp
, &trawname
);
745 work
->constructor
-= 1;
747 string_delete(&trawname
);
748 string_delete(&tname
);
754 /* At the outermost level, we cannot have a return type specified,
755 so if we run into another '_' at this point we are dealing with
756 a mangled name that is either bogus, or has been mangled by
757 some algorithm we don't know how to deal with. So just
758 reject the entire demangling. */
763 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
765 /* Assume we have stumbled onto the first outermost function
766 argument token, and start processing args. */
768 success
= demangle_args (work
, mangled
, declp
);
772 /* Non-GNU demanglers use a specific token to mark the start
773 of the outermost function argument tokens. Typically 'F',
774 for ARM-demangling, for example. So if we find something
775 we are not prepared for, it must be an error. */
781 if (AUTO_DEMANGLING || GNU_DEMANGLING)
784 if (success
&& expect_func
)
787 success
= demangle_args (work
, mangled
, declp
);
791 if (success
&& !func_done
)
793 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
795 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
796 bar__3fooi is 'foo::bar(int)'. We get here when we find the
797 first case, and need to ensure that the '(void)' gets added to
798 the current declp. Note that with ARM, the first case
799 represents the name of a static data member 'foo::bar',
800 which is in the current declp, so we leave it alone. */
801 success
= demangle_args (work
, mangled
, declp
);
804 if (success
&& work
-> static_type
&& PRINT_ARG_TYPES
)
806 string_append (declp
, " static");
808 if (success
&& work
-> const_type
&& PRINT_ARG_TYPES
)
810 string_append (declp
, " const");
818 demangle_method_args (work
, mangled
, declp
)
819 struct work_stuff
*work
;
820 const char **mangled
;
825 if (work
-> static_type
)
827 string_append (declp
, *mangled
+ 1);
828 *mangled
+= strlen (*mangled
);
833 success
= demangle_args (work
, mangled
, declp
);
841 demangle_template (work
, mangled
, tname
, trawname
)
842 struct work_stuff
*work
;
843 const char **mangled
;
864 /* get template name */
865 if ((r
= consume_count (mangled
)) == 0 || strlen (*mangled
) < r
)
870 string_appendn (trawname
, *mangled
, r
);
871 string_appendn (tname
, *mangled
, r
);
873 string_append (tname
, "<");
874 /* get size of template parameter list */
875 if (!get_count (mangled
, &r
))
879 for (i
= 0; i
< r
; i
++)
883 string_append (tname
, ", ");
885 /* Z for type parameters */
886 if (**mangled
== 'Z')
889 /* temp is initialized in do_type */
890 success
= do_type (work
, mangled
, &temp
);
893 string_appends (tname
, &temp
);
895 string_delete(&temp
);
903 /* otherwise, value parameter */
911 /* temp is initialized in do_type */
912 success
= do_type (work
, mangled
, &temp
);
916 string_appends (tname, &temp);
919 string_delete(&temp
);
925 string_append (tname, "=");
927 while (*old_p
&& !done
)
934 done
= is_pointer
= 1;
936 case 'C': /* const */
937 case 'S': /* explicitly signed [char] */
938 case 'U': /* unsigned */
939 case 'V': /* volatile */
940 case 'F': /* function */
941 case 'M': /* member function */
943 case 'J': /* complex */
946 case 'Q': /* qualified name */
947 done
= is_integral
= 1;
949 case 'T': /* remembered type */
955 case 'x': /* long long */
958 case 's': /* short */
959 case 'w': /* wchar_t */
960 done
= is_integral
= 1;
968 case 'r': /* long double */
969 case 'd': /* double */
970 case 'f': /* float */
974 /* it's probably user defined type, let's assume
975 it's integral, it seems hard to figure out
977 done
= is_integral
= 1;
982 if (**mangled
== 'm')
984 string_appendn (tname
, "-", 1);
987 while (isdigit (**mangled
))
989 string_appendn (tname
, *mangled
, 1);
997 if (**mangled
== 'm')
999 string_appendn (tname
, "-", 1);
1002 string_appendn (tname
, "'", 1);
1003 val
= consume_count(mangled
);
1011 string_appendn (tname
, &tmp
[0], 1);
1012 string_appendn (tname
, "'", 1);
1016 int val
= consume_count (mangled
);
1018 string_appendn (tname
, "false", 5);
1020 string_appendn (tname
, "true", 4);
1026 if (**mangled
== 'm')
1028 string_appendn (tname
, "-", 1);
1031 while (isdigit (**mangled
))
1033 string_appendn (tname
, *mangled
, 1);
1036 if (**mangled
== '.') /* fraction */
1038 string_appendn (tname
, ".", 1);
1040 while (isdigit (**mangled
))
1042 string_appendn (tname
, *mangled
, 1);
1046 if (**mangled
== 'e') /* exponent */
1048 string_appendn (tname
, "e", 1);
1050 while (isdigit (**mangled
))
1052 string_appendn (tname
, *mangled
, 1);
1057 else if (is_pointer
)
1059 symbol_len
= consume_count (mangled
);
1060 if (symbol_len
== 0)
1065 if (symbol_len
== 0)
1066 string_appendn (tname
, "0", 1);
1069 char *p
= xmalloc (symbol_len
+ 1), *q
;
1070 strncpy (p
, *mangled
, symbol_len
);
1071 p
[symbol_len
] = '\0';
1072 q
= cplus_demangle (p
, work
->options
);
1073 string_appendn (tname
, "&", 1);
1076 string_append (tname
, q
);
1080 string_append (tname
, p
);
1083 *mangled
+= symbol_len
;
1088 if (tname
->p
[-1] == '>')
1089 string_append (tname
, " ");
1090 string_append (tname
, ">");
1093 if (work -> static_type)
1095 string_append (declp, *mangled + 1);
1096 *mangled += strlen (*mangled);
1101 success = demangle_args (work, mangled, declp);
1109 arm_pt (work
, mangled
, n
, anchor
, args
)
1110 struct work_stuff
*work
;
1111 const char *mangled
;
1113 const char **anchor
, **args
;
1116 if (ARM_DEMANGLING
&& (*anchor
= mystrstr (mangled
, "__pt__")))
1119 *args
= *anchor
+ 6;
1120 len
= consume_count (args
);
1121 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1131 demangle_arm_pt (work
, mangled
, n
, declp
)
1132 struct work_stuff
*work
;
1133 const char **mangled
;
1139 const char *e
= *mangled
+ n
;
1142 if (arm_pt (work
, *mangled
, n
, &p
, &args
))
1146 string_appendn (declp
, *mangled
, p
- *mangled
);
1147 string_append (declp
, "<");
1148 /* should do error checking here */
1150 string_clear (&arg
);
1151 do_type (work
, &args
, &arg
);
1152 string_appends (declp
, &arg
);
1153 string_append (declp
, ",");
1155 string_delete (&arg
);
1157 string_append (declp
, ">");
1161 string_appendn (declp
, *mangled
, n
);
1167 demangle_class_name (work
, mangled
, declp
)
1168 struct work_stuff
*work
;
1169 const char **mangled
;
1175 n
= consume_count (mangled
);
1176 if (strlen (*mangled
) >= n
)
1178 demangle_arm_pt (work
, mangled
, n
, declp
);
1189 demangle_class -- demangle a mangled class sequence
1194 demangle_class (struct work_stuff *work, const char **mangled,
1199 DECLP points to the buffer into which demangling is being done.
1201 *MANGLED points to the current token to be demangled. On input,
1202 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1203 On exit, it points to the next token after the mangled class on
1204 success, or the first unconsumed token on failure.
1206 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1207 we are demangling a constructor or destructor. In this case
1208 we prepend "class::class" or "class::~class" to DECLP.
1210 Otherwise, we prepend "class::" to the current DECLP.
1212 Reset the constructor/destructor flags once they have been
1213 "consumed". This allows demangle_class to be called later during
1214 the same demangling, to do normal class demangling.
1216 Returns 1 if demangling is successful, 0 otherwise.
1221 demangle_class (work
, mangled
, declp
)
1222 struct work_stuff
*work
;
1223 const char **mangled
;
1229 string_init (&class_name
);
1230 if (demangle_class_name (work
, mangled
, &class_name
))
1232 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1234 string_prepends (declp
, &class_name
);
1235 if (work
-> destructor
& 1)
1237 string_prepend (declp
, "~");
1238 work
-> destructor
-= 1;
1242 work
-> constructor
-= 1;
1245 string_prepend (declp
, "::");
1246 string_prepends (declp
, &class_name
);
1249 string_delete (&class_name
);
1257 demangle_prefix -- consume the mangled name prefix and find signature
1262 demangle_prefix (struct work_stuff *work, const char **mangled,
1267 Consume and demangle the prefix of the mangled name.
1269 DECLP points to the string buffer into which demangled output is
1270 placed. On entry, the buffer is empty. On exit it contains
1271 the root function name, the demangled operator name, or in some
1272 special cases either nothing or the completely demangled result.
1274 MANGLED points to the current pointer into the mangled name. As each
1275 token of the mangled name is consumed, it is updated. Upon entry
1276 the current mangled name pointer points to the first character of
1277 the mangled name. Upon exit, it should point to the first character
1278 of the signature if demangling was successful, or to the first
1279 unconsumed character if demangling of the prefix was unsuccessful.
1281 Returns 1 on success, 0 otherwise.
1285 demangle_prefix (work
, mangled
, declp
)
1286 struct work_stuff
*work
;
1287 const char **mangled
;
1294 if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
1296 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
1297 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
1299 if ((*mangled
)[9] == 'D')
1301 /* it's a GNU global destructor to be executed at program exit */
1303 work
->destructor
= 2;
1304 if (gnu_special (work
, mangled
, declp
))
1307 else if ((*mangled
)[9] == 'I')
1309 /* it's a GNU global constructor to be executed at program init */
1311 work
->constructor
= 2;
1312 if (gnu_special (work
, mangled
, declp
))
1317 else if (ARM_DEMANGLING
&& strncmp(*mangled
, "__std__", 7) == 0)
1319 /* it's a ARM global destructor to be executed at program exit */
1321 work
->destructor
= 2;
1323 else if (ARM_DEMANGLING
&& strncmp(*mangled
, "__sti__", 7) == 0)
1325 /* it's a ARM global constructor to be executed at program initial */
1327 work
->constructor
= 2;
1330 /* This block of code is a reduction in strength time optimization
1332 scan = mystrstr (*mangled, "__"); */
1338 scan
= strchr (scan
, '_');
1339 } while (scan
!= NULL
&& *++scan
!= '_');
1341 if (scan
!= NULL
) --scan
;
1346 /* We found a sequence of two or more '_', ensure that we start at
1347 the last pair in the sequence. */
1348 i
= strspn (scan
, "_");
1359 else if (work
-> static_type
)
1361 if (!isdigit (scan
[0]) && (scan
[0] != 't'))
1366 else if ((scan
== *mangled
)
1367 && (isdigit (scan
[2]) || (scan
[2] == 'Q') || (scan
[2] == 't')))
1369 /* The ARM says nothing about the mangling of local variables.
1370 But cfront mangles local variables by prepending __<nesting_level>
1371 to them. As an extension to ARM demangling we handle this case. */
1372 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
) && isdigit (scan
[2]))
1374 *mangled
= scan
+ 2;
1375 consume_count (mangled
);
1376 string_append (declp
, *mangled
);
1377 *mangled
+= strlen (*mangled
);
1382 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1383 names like __Q2_3foo3bar for nested type names. So don't accept
1384 this style of constructor for cfront demangling. */
1385 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
))
1386 work
-> constructor
+= 1;
1387 *mangled
= scan
+ 2;
1390 else if ((scan
== *mangled
) && !isdigit (scan
[2]) && (scan
[2] != 't'))
1392 /* Mangled name starts with "__". Skip over any leading '_' characters,
1393 then find the next "__" that separates the prefix from the signature.
1395 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
)
1396 || (arm_special (work
, mangled
, declp
) == 0))
1398 while (*scan
== '_')
1402 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
1404 /* No separator (I.E. "__not_mangled"), or empty signature
1405 (I.E. "__not_mangled_either__") */
1410 demangle_function_name (work
, mangled
, declp
, scan
);
1414 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
1416 /* Cfront-style parameterized type. Handled later as a signature. */
1420 demangle_arm_pt (work
, mangled
, strlen (*mangled
), declp
);
1422 else if (*(scan
+ 2) != '\0')
1424 /* Mangled name does not start with "__" but does have one somewhere
1425 in there with non empty stuff after it. Looks like a global
1427 demangle_function_name (work
, mangled
, declp
, scan
);
1431 /* Doesn't look like a mangled name */
1435 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
1437 string_append (declp
, *mangled
);
1438 *mangled
+= strlen (*mangled
);
1448 gnu_special -- special handling of gnu mangled strings
1453 gnu_special (struct work_stuff *work, const char **mangled,
1459 Process some special GNU style mangling forms that don't fit
1460 the normal pattern. For example:
1462 _$_3foo (destructor for class foo)
1463 _vt$foo (foo virtual table)
1464 _vt$foo$bar (foo::bar virtual table)
1465 __vt_foo (foo virtual table, new style with thunks)
1466 _3foo$varname (static data member)
1467 _Q22rs2tu$vw (static data member)
1468 __t6vector1Zii (constructor with template)
1469 __thunk_4__$_7ostream (virtual function thunk)
1473 gnu_special (work
, mangled
, declp
)
1474 struct work_stuff
*work
;
1475 const char **mangled
;
1482 if ((*mangled
)[0] == '_'
1483 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
1484 && (*mangled
)[2] == '_')
1486 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1488 work
-> destructor
+= 1;
1490 else if ((*mangled
)[0] == '_'
1491 && (((*mangled
)[1] == '_'
1492 && (*mangled
)[2] == 'v'
1493 && (*mangled
)[3] == 't'
1494 && (*mangled
)[4] == '_')
1495 || ((*mangled
)[1] == 'v'
1496 && (*mangled
)[2] == 't'
1497 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
1499 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1500 and create the decl. Note that we consume the entire mangled
1501 input string, which means that demangle_signature has no work
1503 if ((*mangled
)[2] == 'v')
1504 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
1506 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1507 while (**mangled
!= '\0')
1509 p
= strpbrk (*mangled
, cplus_markers
);
1513 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
1516 success
= demangle_template (work
, mangled
, declp
, 0);
1519 if (isdigit(*mangled
[0]))
1521 n
= consume_count(mangled
);
1525 n
= strcspn (*mangled
, cplus_markers
);
1527 string_appendn (declp
, *mangled
, n
);
1531 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
1535 string_append (declp
, "::");
1546 string_append (declp
, " virtual table");
1548 else if ((*mangled
)[0] == '_'
1549 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
1550 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
1552 /* static data member, "_3foo$varname" for example */
1557 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
1560 success
= demangle_template (work
, mangled
, declp
, 0);
1563 n
= consume_count (mangled
);
1564 string_appendn (declp
, *mangled
, n
);
1567 if (success
&& (p
== *mangled
))
1569 /* Consumed everything up to the cplus_marker, append the
1572 string_append (declp
, "::");
1573 n
= strlen (*mangled
);
1574 string_appendn (declp
, *mangled
, n
);
1582 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
1584 int delta
= ((*mangled
) += 8, consume_count (mangled
));
1585 char *method
= cplus_demangle (++*mangled
, work
->options
);
1589 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
1590 string_append (declp
, buf
);
1591 string_append (declp
, method
);
1593 n
= strlen (*mangled
);
1601 else if (strncmp (*mangled
, "__t", 3) == 0
1602 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
1604 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
1609 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
1612 success
= demangle_template (work
, mangled
, declp
, 0);
1615 success
= demangle_fund_type (work
, mangled
, declp
);
1618 if (success
&& **mangled
!= '\0')
1621 string_append (declp
, p
);
1634 arm_special -- special handling of ARM/lucid mangled strings
1639 arm_special (struct work_stuff *work, const char **mangled,
1645 Process some special ARM style mangling forms that don't fit
1646 the normal pattern. For example:
1648 __vtbl__3foo (foo virtual table)
1649 __vtbl__3foo__3bar (bar::foo virtual table)
1654 arm_special (work
, mangled
, declp
)
1655 struct work_stuff
*work
;
1656 const char **mangled
;
1663 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
1665 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1666 and create the decl. Note that we consume the entire mangled
1667 input string, which means that demangle_signature has no work
1669 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
1670 while (*scan
!= '\0') /* first check it can be demangled */
1672 n
= consume_count (&scan
);
1675 return (0); /* no good */
1678 if (scan
[0] == '_' && scan
[1] == '_')
1683 (*mangled
) += ARM_VTABLE_STRLEN
;
1684 while (**mangled
!= '\0')
1686 n
= consume_count (mangled
);
1687 string_prependn (declp
, *mangled
, n
);
1689 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
1691 string_prepend (declp
, "::");
1695 string_append (declp
, " virtual table");
1708 demangle_qualified -- demangle 'Q' qualified name strings
1713 demangle_qualified (struct work_stuff *, const char *mangled,
1714 string *result, int isfuncname, int append);
1718 Demangle a qualified name, such as "Q25Outer5Inner" which is
1719 the mangled form of "Outer::Inner". The demangled output is
1720 prepended or appended to the result string according to the
1721 state of the append flag.
1723 If isfuncname is nonzero, then the qualified name we are building
1724 is going to be used as a member function name, so if it is a
1725 constructor or destructor function, append an appropriate
1726 constructor or destructor name. I.E. for the above example,
1727 the result for use as a constructor is "Outer::Inner::Inner"
1728 and the result for use as a destructor is "Outer::Inner::~Inner".
1732 Numeric conversion is ASCII dependent (FIXME).
1737 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
1738 struct work_stuff
*work
;
1739 const char **mangled
;
1751 string_init (&temp
);
1752 switch ((*mangled
)[1])
1755 /* GNU mangled name with more than 9 classes. The count is preceded
1756 by an underscore (to distinguish it from the <= 9 case) and followed
1757 by an underscore. */
1759 qualifiers
= atoi (p
);
1760 if (!isdigit (*p
) || *p
== '0')
1763 /* Skip the digits. */
1764 while (isdigit (*p
))
1782 /* The count is in a single digit. */
1783 num
[0] = (*mangled
)[1];
1785 qualifiers
= atoi (num
);
1787 /* If there is an underscore after the digit, skip it. This is
1788 said to be for ARM-qualified names, but the ARM makes no
1789 mention of such an underscore. Perhaps cfront uses one. */
1790 if ((*mangled
)[2] == '_')
1805 /* Pick off the names and collect them in the temp buffer in the order
1806 in which they are found, separated by '::'. */
1808 while (qualifiers
-- > 0)
1810 if (*mangled
[0] == '_')
1811 *mangled
= *mangled
+ 1;
1812 if (*mangled
[0] == 't')
1814 success
= demangle_template(work
, mangled
, &temp
, 0);
1815 if (!success
) break;
1819 namelength
= consume_count (mangled
);
1820 if (strlen (*mangled
) < namelength
)
1822 /* Simple sanity check failed */
1826 string_appendn (&temp
, *mangled
, namelength
);
1827 *mangled
+= namelength
;
1831 string_appendn (&temp
, "::", 2);
1835 /* If we are using the result as a function name, we need to append
1836 the appropriate '::' separated constructor or destructor name.
1837 We do this here because this is the most convenient place, where
1838 we already have a pointer to the name and the length of the name. */
1840 if (isfuncname
&& (work
->constructor
& 1 || work
->destructor
& 1))
1842 string_appendn (&temp
, "::", 2);
1843 if (work
-> destructor
& 1)
1845 string_append (&temp
, "~");
1847 string_appendn (&temp
, (*mangled
) - namelength
, namelength
);
1850 /* Now either prepend the temp buffer to the result, or append it,
1851 depending upon the state of the append flag. */
1855 string_appends (result
, &temp
);
1859 if (!STRING_EMPTY (result
))
1861 string_appendn (&temp
, "::", 2);
1863 string_prepends (result
, &temp
);
1866 string_delete (&temp
);
1874 get_count -- convert an ascii count to integer, consuming tokens
1879 get_count (const char **type, int *count)
1883 Return 0 if no conversion is performed, 1 if a string is converted.
1887 get_count (type
, count
)
1894 if (!isdigit (**type
))
1900 *count
= **type
- '0';
1902 if (isdigit (**type
))
1912 while (isdigit (*p
));
1923 /* result will be initialised here; it will be freed on failure */
1926 do_type (work
, mangled
, result
)
1927 struct work_stuff
*work
;
1928 const char **mangled
;
1935 const char *remembered_type
;
1939 string_init (&decl
);
1940 string_init (result
);
1944 while (success
&& !done
)
1950 /* A pointer type */
1954 string_prepend (&decl
, "*");
1957 /* A reference type */
1960 string_prepend (&decl
, "&");
1966 const char *p
= ++(*mangled
);
1968 string_prepend (&decl
, "(");
1969 string_append (&decl
, ")[");
1970 /* Copy anything up until the next underscore (the size of the
1972 while (**mangled
&& **mangled
!= '_')
1974 if (**mangled
== '_')
1976 string_appendn (&decl
, p
, *mangled
- p
);
1977 string_append (&decl
, "]");
1985 /* A back reference to a previously seen type */
1988 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
1994 remembered_type
= work
-> typevec
[n
];
1995 mangled
= &remembered_type
;
2002 if (!STRING_EMPTY (&decl
) && decl
.b
[0] == '*')
2004 string_prepend (&decl
, "(");
2005 string_append (&decl
, ")");
2007 /* After picking off the function args, we expect to either find the
2008 function return type (preceded by an '_') or the end of the
2010 if (!demangle_args (work
, mangled
, &decl
)
2011 || (**mangled
!= '_' && **mangled
!= '\0'))
2015 if (success
&& (**mangled
== '_'))
2027 member
= **mangled
== 'M';
2029 if (!isdigit (**mangled
) && **mangled
!= 't')
2035 string_append (&decl
, ")");
2036 string_prepend (&decl
, "::");
2037 if (isdigit (**mangled
))
2039 n
= consume_count (mangled
);
2040 if (strlen (*mangled
) < n
)
2045 string_prependn (&decl
, *mangled
, n
);
2051 string_init (&temp
);
2052 success
= demangle_template (work
, mangled
, &temp
, NULL
);
2055 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
2056 string_clear (&temp
);
2061 string_prepend (&decl
, "(");
2064 if (**mangled
== 'C')
2069 if (**mangled
== 'V')
2074 if (*(*mangled
)++ != 'F')
2080 if ((member
&& !demangle_args (work
, mangled
, &decl
))
2081 || **mangled
!= '_')
2087 if (! PRINT_ANSI_QUALIFIERS
)
2093 APPEND_BLANK (&decl
);
2094 string_append (&decl
, "const");
2098 APPEND_BLANK (&decl
);
2099 string_append (&decl
, "volatile");
2110 if ((*mangled)[1] == 'P')
2113 if (PRINT_ANSI_QUALIFIERS
)
2115 if (!STRING_EMPTY (&decl
))
2117 string_prepend (&decl
, " ");
2119 string_prepend (&decl
, "const");
2135 /* A qualified name, such as "Outer::Inner". */
2137 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
2141 success
= demangle_fund_type (work
, mangled
, result
);
2147 if (!STRING_EMPTY (&decl
))
2149 string_append (result
, " ");
2150 string_appends (result
, &decl
);
2155 string_delete (result
);
2157 string_delete (&decl
);
2161 /* Given a pointer to a type string that represents a fundamental type
2162 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2163 string in which the demangled output is being built in RESULT, and
2164 the WORK structure, decode the types and add them to the result.
2169 "Sl" => "signed long"
2170 "CUs" => "const unsigned short"
2175 demangle_fund_type (work
, mangled
, result
)
2176 struct work_stuff
*work
;
2177 const char **mangled
;
2183 /* First pick off any type qualifiers. There can be more than one. */
2191 if (PRINT_ANSI_QUALIFIERS
)
2193 APPEND_BLANK (result
);
2194 string_append (result
, "const");
2199 APPEND_BLANK (result
);
2200 string_append (result
, "unsigned");
2202 case 'S': /* signed char only */
2204 APPEND_BLANK (result
);
2205 string_append (result
, "signed");
2209 if (PRINT_ANSI_QUALIFIERS
)
2211 APPEND_BLANK (result
);
2212 string_append (result
, "volatile");
2217 APPEND_BLANK (result
);
2218 string_append (result
, "complex");
2226 /* Now pick off the fundamental type. There can be only one. */
2235 APPEND_BLANK (result
);
2236 string_append (result
, "void");
2240 APPEND_BLANK (result
);
2241 string_append (result
, "long long");
2245 APPEND_BLANK (result
);
2246 string_append (result
, "long");
2250 APPEND_BLANK (result
);
2251 string_append (result
, "int");
2255 APPEND_BLANK (result
);
2256 string_append (result
, "short");
2260 APPEND_BLANK (result
);
2261 string_append (result
, "bool");
2265 APPEND_BLANK (result
);
2266 string_append (result
, "char");
2270 APPEND_BLANK (result
);
2271 string_append (result
, "wchar_t");
2275 APPEND_BLANK (result
);
2276 string_append (result
, "long double");
2280 APPEND_BLANK (result
);
2281 string_append (result
, "double");
2285 APPEND_BLANK (result
);
2286 string_append (result
, "float");
2290 if (!isdigit (**mangled
))
2296 /* An explicit type, such as "6mytype" or "7integer" */
2307 APPEND_BLANK (result
);
2308 if (!demangle_class_name (work
, mangled
, result
)) {
2314 success
= demangle_template(work
,mangled
, result
, 0);
2324 /* `result' will be initialized in do_type; it will be freed on failure */
2327 do_arg (work
, mangled
, result
)
2328 struct work_stuff
*work
;
2329 const char **mangled
;
2332 const char *start
= *mangled
;
2334 if (!do_type (work
, mangled
, result
))
2340 remember_type (work
, start
, *mangled
- start
);
2346 remember_type (work
, start
, len
)
2347 struct work_stuff
*work
;
2353 if (work
-> ntypes
>= work
-> typevec_size
)
2355 if (work
-> typevec_size
== 0)
2357 work
-> typevec_size
= 3;
2359 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
2363 work
-> typevec_size
*= 2;
2365 = (char **) xrealloc ((char *)work
-> typevec
,
2366 sizeof (char *) * work
-> typevec_size
);
2369 tem
= xmalloc (len
+ 1);
2370 memcpy (tem
, start
, len
);
2372 work
-> typevec
[work
-> ntypes
++] = tem
;
2375 /* Forget the remembered types, but not the type vector itself. */
2379 struct work_stuff
*work
;
2383 while (work
-> ntypes
> 0)
2385 i
= --(work
-> ntypes
);
2386 if (work
-> typevec
[i
] != NULL
)
2388 free (work
-> typevec
[i
]);
2389 work
-> typevec
[i
] = NULL
;
2394 /* Process the argument list part of the signature, after any class spec
2395 has been consumed, as well as the first 'F' character (if any). For
2398 "__als__3fooRT0" => process "RT0"
2399 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2401 DECLP must be already initialised, usually non-empty. It won't be freed
2404 Note that g++ differs significantly from ARM and lucid style mangling
2405 with regards to references to previously seen types. For example, given
2406 the source fragment:
2410 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2413 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2414 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2416 g++ produces the names:
2421 while lcc (and presumably other ARM style compilers as well) produces:
2423 foo__FiR3fooT1T2T1T2
2424 __ct__3fooFiR3fooT1T2T1T2
2426 Note that g++ bases it's type numbers starting at zero and counts all
2427 previously seen types, while lucid/ARM bases it's type numbers starting
2428 at one and only considers types after it has seen the 'F' character
2429 indicating the start of the function args. For lucid/ARM style, we
2430 account for this difference by discarding any previously seen types when
2431 we see the 'F' character, and subtracting one from the type number
2437 demangle_args (work
, mangled
, declp
)
2438 struct work_stuff
*work
;
2439 const char **mangled
;
2449 if (PRINT_ARG_TYPES
)
2451 string_append (declp
, "(");
2452 if (**mangled
== '\0')
2454 string_append (declp
, "void");
2458 while (**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
2460 if ((**mangled
== 'N') || (**mangled
== 'T'))
2462 temptype
= *(*mangled
)++;
2464 if (temptype
== 'N')
2466 if (!get_count (mangled
, &r
))
2475 if (ARM_DEMANGLING
&& work
-> ntypes
>= 10)
2477 /* If we have 10 or more types we might have more than a 1 digit
2478 index so we'll have to consume the whole count here. This
2479 will lose if the next thing is a type name preceded by a
2480 count but it's impossible to demangle that case properly
2481 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2482 Pc, ...)" or "(..., type12, char *, ...)" */
2483 if ((t
= consume_count(mangled
)) == 0)
2490 if (!get_count (mangled
, &t
))
2495 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
)
2499 /* Validate the type index. Protect against illegal indices from
2500 malformed type strings. */
2501 if ((t
< 0) || (t
>= work
-> ntypes
))
2507 tem
= work
-> typevec
[t
];
2508 if (need_comma
&& PRINT_ARG_TYPES
)
2510 string_append (declp
, ", ");
2512 if (!do_arg (work
, &tem
, &arg
))
2516 if (PRINT_ARG_TYPES
)
2518 string_appends (declp
, &arg
);
2520 string_delete (&arg
);
2526 if (need_comma
& PRINT_ARG_TYPES
)
2528 string_append (declp
, ", ");
2530 if (!do_arg (work
, mangled
, &arg
))
2534 if (PRINT_ARG_TYPES
)
2536 string_appends (declp
, &arg
);
2538 string_delete (&arg
);
2543 if (**mangled
== 'e')
2546 if (PRINT_ARG_TYPES
)
2550 string_append (declp
, ",");
2552 string_append (declp
, "...");
2556 if (PRINT_ARG_TYPES
)
2558 string_append (declp
, ")");
2564 demangle_function_name (work
, mangled
, declp
, scan
)
2565 struct work_stuff
*work
;
2566 const char **mangled
;
2575 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
2576 string_need (declp
, 1);
2577 *(declp
-> p
) = '\0';
2579 /* Consume the function name, including the "__" separating the name
2580 from the signature. We are guaranteed that SCAN points to the
2583 (*mangled
) = scan
+ 2;
2585 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
)
2588 /* See if we have an ARM style constructor or destructor operator.
2589 If so, then just record it, clear the decl, and return.
2590 We can't build the actual constructor/destructor decl until later,
2591 when we recover the class name from the signature. */
2593 if (strcmp (declp
-> b
, "__ct") == 0)
2595 work
-> constructor
+= 1;
2596 string_clear (declp
);
2599 else if (strcmp (declp
-> b
, "__dt") == 0)
2601 work
-> destructor
+= 1;
2602 string_clear (declp
);
2607 if (declp
->p
- declp
->b
>= 3
2608 && declp
->b
[0] == 'o'
2609 && declp
->b
[1] == 'p'
2610 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
2612 /* see if it's an assignment expression */
2613 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
2614 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
2616 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
2618 len
= declp
->p
- declp
->b
- 10;
2619 if (strlen (optable
[i
].in
) == len
2620 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
2622 string_clear (declp
);
2623 string_append (declp
, "operator");
2624 string_append (declp
, optable
[i
].out
);
2625 string_append (declp
, "=");
2632 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
2634 int len
= declp
->p
- declp
->b
- 3;
2635 if (strlen (optable
[i
].in
) == len
2636 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
2638 string_clear (declp
);
2639 string_append (declp
, "operator");
2640 string_append (declp
, optable
[i
].out
);
2646 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
2647 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
2649 /* type conversion operator */
2651 if (do_type (work
, &tem
, &type
))
2653 string_clear (declp
);
2654 string_append (declp
, "operator ");
2655 string_appends (declp
, &type
);
2656 string_delete (&type
);
2659 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
2660 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
2663 /* type conversion operator. */
2665 if (do_type (work
, &tem
, &type
))
2667 string_clear (declp
);
2668 string_append (declp
, "operator ");
2669 string_appends (declp
, &type
);
2670 string_delete (&type
);
2673 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
2674 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
2675 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
2677 if (declp
->b
[4] == '\0')
2680 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
2682 if (strlen (optable
[i
].in
) == 2
2683 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
2685 string_clear (declp
);
2686 string_append (declp
, "operator");
2687 string_append (declp
, optable
[i
].out
);
2694 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
2697 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
2699 if (strlen (optable
[i
].in
) == 3
2700 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
2702 string_clear (declp
);
2703 string_append (declp
, "operator");
2704 string_append (declp
, optable
[i
].out
);
2713 /* a mini string-handling package */
2728 s
->p
= s
->b
= xmalloc (n
);
2731 else if (s
->e
- s
->p
< n
)
2736 s
->b
= xrealloc (s
->b
, n
);
2749 s
->b
= s
->e
= s
->p
= NULL
;
2757 s
->b
= s
->p
= s
->e
= NULL
;
2773 return (s
->b
== s
->p
);
2779 string_append (p
, s
)
2784 if (s
== NULL
|| *s
== '\0')
2788 memcpy (p
->p
, s
, n
);
2793 string_appends (p
, s
)
2802 memcpy (p
->p
, s
->b
, n
);
2808 string_appendn (p
, s
, n
)
2816 memcpy (p
->p
, s
, n
);
2822 string_prepend (p
, s
)
2826 if (s
!= NULL
&& *s
!= '\0')
2828 string_prependn (p
, s
, strlen (s
));
2833 string_prepends (p
, s
)
2838 string_prependn (p
, s
->b
, s
->p
- s
->b
);
2843 string_prependn (p
, s
, n
)
2853 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
2857 memcpy (p
->b
, s
, n
);
2862 /* To generate a standalone demangler program for testing purposes,
2863 just compile and link this file with -DMAIN and libiberty.a. When
2864 run, it demangles each command line arg, or each stdin string, and
2865 prints the result on stdout. */
2870 demangle_it (mangled_name
)
2875 result
= cplus_demangle (mangled_name
, DMGL_PARAMS
| DMGL_ANSI
);
2878 printf ("%s\n", mangled_name
);
2882 printf ("%s\n", result
);
2889 static char *program_name
;
2890 static char *program_version
= VERSION
;
2893 usage (stream
, status
)
2898 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2899 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2900 [--help] [--version] [arg...]\n",
2905 #define MBUF_SIZE 512
2906 char mbuffer
[MBUF_SIZE
];
2908 /* Defined in the automatically-generated underscore.c. */
2909 extern int prepends_underscore
;
2911 int strip_underscore
= 0;
2913 static struct option long_options
[] = {
2914 {"strip-underscores", no_argument
, 0, '_'},
2915 {"format", required_argument
, 0, 's'},
2916 {"help", no_argument
, 0, 'h'},
2917 {"no-strip-underscores", no_argument
, 0, 'n'},
2918 {"version", no_argument
, 0, 'v'},
2919 {0, no_argument
, 0, 0}
2930 program_name
= argv
[0];
2932 strip_underscore
= prepends_underscore
;
2934 while ((c
= getopt_long (argc
, argv
, "_ns:", long_options
, (int *) 0)) != EOF
)
2944 strip_underscore
= 0;
2947 printf ("GNU %s version %s\n", program_name
, program_version
);
2950 strip_underscore
= 1;
2953 if (strcmp (optarg
, "gnu") == 0)
2955 current_demangling_style
= gnu_demangling
;
2957 else if (strcmp (optarg
, "lucid") == 0)
2959 current_demangling_style
= lucid_demangling
;
2961 else if (strcmp (optarg
, "arm") == 0)
2963 current_demangling_style
= arm_demangling
;
2967 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
2968 program_name
, optarg
);
2977 for ( ; optind
< argc
; optind
++)
2979 demangle_it (argv
[optind
]);
2988 /* Try to read a label. */
2989 while (c
!= EOF
&& (isalnum(c
) || c
== '_' || c
== '$' || c
== '.'))
2991 if (i
>= MBUF_SIZE
-1)
3000 if (mbuffer
[0] == '.')
3002 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
3010 result
= cplus_demangle (mbuffer
+ skip_first
,
3011 DMGL_PARAMS
| DMGL_ANSI
);
3014 if (mbuffer
[0] == '.')
3016 fputs (result
, stdout
);
3020 fputs (mbuffer
, stdout
);
3037 fprintf (stderr
, "%s: %s\n", program_name
, str
);
3048 register char *value
= (char *) malloc (size
);
3050 fatal ("virtual memory exhausted");
3055 xrealloc (ptr
, size
)
3059 register char *value
= (char *) realloc (ptr
, size
);
3061 fatal ("virtual memory exhausted");