Call fatal_insn_not_found instead of abort
[official-gcc.git] / gcc / cplus-dem.c
blobb05c948481bb0e2241efa3f7a81e69454df53ec2
1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 This file is part of the libiberty library.
7 Libiberty is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 Libiberty is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with libiberty; see the file COPYING.LIB. If
19 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
24 This file imports xmalloc and xrealloc, which are like malloc and
25 realloc except that they generate a fatal error if there is no
26 available memory. */
28 /* This file lives in both GCC and libiberty. When making changes, please
29 try not to break either. */
31 #include <ctype.h>
32 #include <sys/types.h>
33 #include <string.h>
34 #include <stdio.h>
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
40 #include <demangle.h>
41 #undef CURRENT_DEMANGLING_STYLE
42 #define CURRENT_DEMANGLING_STYLE work->options
44 extern char *xmalloc PARAMS((unsigned));
45 extern char *xrealloc PARAMS((char *, unsigned));
47 static const char *mystrstr PARAMS ((const char *, const char *));
49 static const char *
50 mystrstr (s1, s2)
51 const char *s1, *s2;
53 register const char *p = s1;
54 register int len = strlen (s2);
56 for (; (p = strchr (p, *s2)) != 0; p++)
58 if (strncmp (p, s2, len) == 0)
60 return (p);
63 return (0);
66 /* In order to allow a single demangler executable to demangle strings
67 using various common values of CPLUS_MARKER, as well as any specific
68 one set at compile time, we maintain a string containing all the
69 commonly used ones, and check to see if the marker we are looking for
70 is in that string. CPLUS_MARKER is usually '$' on systems where the
71 assembler can deal with that. Where the assembler can't, it's usually
72 '.' (but on many systems '.' is used for other things). We put the
73 current defined CPLUS_MARKER first (which defaults to '$'), followed
74 by the next most common value, followed by an explicit '$' in case
75 the value of CPLUS_MARKER is not '$'.
77 We could avoid this if we could just get g++ to tell us what the actual
78 cplus marker character is as part of the debug information, perhaps by
79 ensuring that it is the character that terminates the gcc<n>_compiled
80 marker symbol (FIXME). */
82 #if !defined (CPLUS_MARKER)
83 #define CPLUS_MARKER '$'
84 #endif
86 enum demangling_styles current_demangling_style = gnu_demangling;
88 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
90 void
91 set_cplus_marker_for_demangling (ch)
92 int ch;
94 cplus_markers[0] = ch;
97 /* Stuff that is shared between sub-routines.
98 Using a shared structure allows cplus_demangle to be reentrant. */
100 struct work_stuff
102 int options;
103 char **typevec;
104 char **ktypevec;
105 char **btypevec;
106 int numk;
107 int numb;
108 int ksize;
109 int bsize;
110 int ntypes;
111 int typevec_size;
112 int constructor;
113 int destructor;
114 int static_type; /* A static member function */
115 int const_type; /* A const member function */
116 char **tmpl_argvec; /* Template function arguments. */
117 int ntmpl_args; /* The number of template function arguments. */
120 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
121 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
123 static const struct optable
125 const char *in;
126 const char *out;
127 int flags;
128 } optable[] = {
129 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
130 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
131 {"new", " new", 0}, /* old (1.91, and 1.x) */
132 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
133 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
134 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
135 {"as", "=", DMGL_ANSI}, /* ansi */
136 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
137 {"eq", "==", DMGL_ANSI}, /* old, ansi */
138 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
139 {"gt", ">", DMGL_ANSI}, /* old, ansi */
140 {"le", "<=", DMGL_ANSI}, /* old, ansi */
141 {"lt", "<", DMGL_ANSI}, /* old, ansi */
142 {"plus", "+", 0}, /* old */
143 {"pl", "+", DMGL_ANSI}, /* ansi */
144 {"apl", "+=", DMGL_ANSI}, /* ansi */
145 {"minus", "-", 0}, /* old */
146 {"mi", "-", DMGL_ANSI}, /* ansi */
147 {"ami", "-=", DMGL_ANSI}, /* ansi */
148 {"mult", "*", 0}, /* old */
149 {"ml", "*", DMGL_ANSI}, /* ansi */
150 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
151 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
152 {"convert", "+", 0}, /* old (unary +) */
153 {"negate", "-", 0}, /* old (unary -) */
154 {"trunc_mod", "%", 0}, /* old */
155 {"md", "%", DMGL_ANSI}, /* ansi */
156 {"amd", "%=", DMGL_ANSI}, /* ansi */
157 {"trunc_div", "/", 0}, /* old */
158 {"dv", "/", DMGL_ANSI}, /* ansi */
159 {"adv", "/=", DMGL_ANSI}, /* ansi */
160 {"truth_andif", "&&", 0}, /* old */
161 {"aa", "&&", DMGL_ANSI}, /* ansi */
162 {"truth_orif", "||", 0}, /* old */
163 {"oo", "||", DMGL_ANSI}, /* ansi */
164 {"truth_not", "!", 0}, /* old */
165 {"nt", "!", DMGL_ANSI}, /* ansi */
166 {"postincrement","++", 0}, /* old */
167 {"pp", "++", DMGL_ANSI}, /* ansi */
168 {"postdecrement","--", 0}, /* old */
169 {"mm", "--", DMGL_ANSI}, /* ansi */
170 {"bit_ior", "|", 0}, /* old */
171 {"or", "|", DMGL_ANSI}, /* ansi */
172 {"aor", "|=", DMGL_ANSI}, /* ansi */
173 {"bit_xor", "^", 0}, /* old */
174 {"er", "^", DMGL_ANSI}, /* ansi */
175 {"aer", "^=", DMGL_ANSI}, /* ansi */
176 {"bit_and", "&", 0}, /* old */
177 {"ad", "&", DMGL_ANSI}, /* ansi */
178 {"aad", "&=", DMGL_ANSI}, /* ansi */
179 {"bit_not", "~", 0}, /* old */
180 {"co", "~", DMGL_ANSI}, /* ansi */
181 {"call", "()", 0}, /* old */
182 {"cl", "()", DMGL_ANSI}, /* ansi */
183 {"alshift", "<<", 0}, /* old */
184 {"ls", "<<", DMGL_ANSI}, /* ansi */
185 {"als", "<<=", DMGL_ANSI}, /* ansi */
186 {"arshift", ">>", 0}, /* old */
187 {"rs", ">>", DMGL_ANSI}, /* ansi */
188 {"ars", ">>=", DMGL_ANSI}, /* ansi */
189 {"component", "->", 0}, /* old */
190 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
191 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
192 {"indirect", "*", 0}, /* old */
193 {"method_call", "->()", 0}, /* old */
194 {"addr", "&", 0}, /* old (unary &) */
195 {"array", "[]", 0}, /* old */
196 {"vc", "[]", DMGL_ANSI}, /* ansi */
197 {"compound", ", ", 0}, /* old */
198 {"cm", ", ", DMGL_ANSI}, /* ansi */
199 {"cond", "?:", 0}, /* old */
200 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
201 {"max", ">?", 0}, /* old */
202 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
203 {"min", "<?", 0}, /* old */
204 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
205 {"nop", "", 0}, /* old (for operator=) */
206 {"rm", "->*", DMGL_ANSI}, /* ansi */
207 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
211 typedef struct string /* Beware: these aren't required to be */
212 { /* '\0' terminated. */
213 char *b; /* pointer to start of string */
214 char *p; /* pointer after last character */
215 char *e; /* pointer after end of allocated space */
216 } string;
218 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
219 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
220 string_prepend(str, " ");}
221 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
222 string_append(str, " ");}
223 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
225 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
226 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
228 /* Prototypes for local functions */
230 static char *
231 mop_up PARAMS ((struct work_stuff *, string *, int));
233 static void
234 squangle_mop_up PARAMS ((struct work_stuff *));
236 #if 0
237 static int
238 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
239 #endif
241 static char *
242 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
244 static int
245 demangle_template_template_parm PARAMS ((struct work_stuff *work,
246 const char **, string *));
248 static int
249 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
250 string *, int));
252 static int
253 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
254 const char **));
256 static void
257 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
259 static int
260 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
262 static int
263 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
264 int, int));
266 static int
267 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
269 static int
270 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
272 static int
273 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
275 static int
276 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
278 static int
279 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
281 static int
282 arm_special PARAMS ((const char **, string *));
284 static void
285 string_need PARAMS ((string *, int));
287 static void
288 string_delete PARAMS ((string *));
290 static void
291 string_init PARAMS ((string *));
293 static void
294 string_clear PARAMS ((string *));
296 #if 0
297 static int
298 string_empty PARAMS ((string *));
299 #endif
301 static void
302 string_append PARAMS ((string *, const char *));
304 static void
305 string_appends PARAMS ((string *, string *));
307 static void
308 string_appendn PARAMS ((string *, const char *, int));
310 static void
311 string_prepend PARAMS ((string *, const char *));
313 static void
314 string_prependn PARAMS ((string *, const char *, int));
316 static int
317 get_count PARAMS ((const char **, int *));
319 static int
320 consume_count PARAMS ((const char **));
322 static int
323 consume_count_with_underscores PARAMS ((const char**));
325 static int
326 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
328 static int
329 do_type PARAMS ((struct work_stuff *, const char **, string *));
331 static int
332 do_arg PARAMS ((struct work_stuff *, const char **, string *));
334 static void
335 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
336 const char *));
338 static void
339 remember_type PARAMS ((struct work_stuff *, const char *, int));
341 static void
342 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
344 static int
345 register_Btype PARAMS ((struct work_stuff *));
347 static void
348 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
350 static void
351 forget_types PARAMS ((struct work_stuff *));
353 static void
354 forget_B_and_K_types PARAMS ((struct work_stuff *));
356 static void
357 string_prepends PARAMS ((string *, string *));
359 static int
360 demangle_template_value_parm PARAMS ((struct work_stuff*,
361 const char**, string*));
363 /* Translate count to integer, consuming tokens in the process.
364 Conversion terminates on the first non-digit character.
365 Trying to consume something that isn't a count results in
366 no consumption of input and a return of 0. */
368 static int
369 consume_count (type)
370 const char **type;
372 int count = 0;
374 while (isdigit (**type))
376 count *= 10;
377 count += **type - '0';
378 (*type)++;
380 return (count);
384 /* Like consume_count, but for counts that are preceded and followed
385 by '_' if they are greater than 10. Also, -1 is returned for
386 failure, since 0 can be a valid value. */
388 static int
389 consume_count_with_underscores (mangled)
390 const char **mangled;
392 int idx;
394 if (**mangled == '_')
396 (*mangled)++;
397 if (!isdigit (**mangled))
398 return -1;
400 idx = consume_count (mangled);
401 if (**mangled != '_')
402 /* The trailing underscore was missing. */
403 return -1;
405 (*mangled)++;
407 else
409 if (**mangled < '0' || **mangled > '9')
410 return -1;
412 idx = **mangled - '0';
413 (*mangled)++;
416 return idx;
420 cplus_demangle_opname (opname, result, options)
421 const char *opname;
422 char *result;
423 int options;
425 int len, len1, ret;
426 string type;
427 struct work_stuff work[1];
428 const char *tem;
430 len = strlen(opname);
431 result[0] = '\0';
432 ret = 0;
433 work->options = options;
435 if (opname[0] == '_' && opname[1] == '_'
436 && opname[2] == 'o' && opname[3] == 'p')
438 /* ANSI. */
439 /* type conversion operator. */
440 tem = opname + 4;
441 if (do_type (work, &tem, &type))
443 strcat (result, "operator ");
444 strncat (result, type.b, type.p - type.b);
445 string_delete (&type);
446 ret = 1;
449 else if (opname[0] == '_' && opname[1] == '_'
450 && opname[2] >= 'a' && opname[2] <= 'z'
451 && opname[3] >= 'a' && opname[3] <= 'z')
453 if (opname[4] == '\0')
455 /* Operator. */
456 size_t i;
457 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
459 if (strlen (optable[i].in) == 2
460 && memcmp (optable[i].in, opname + 2, 2) == 0)
462 strcat (result, "operator");
463 strcat (result, optable[i].out);
464 ret = 1;
465 break;
469 else
471 if (opname[2] == 'a' && opname[5] == '\0')
473 /* Assignment. */
474 size_t i;
475 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
477 if (strlen (optable[i].in) == 3
478 && memcmp (optable[i].in, opname + 2, 3) == 0)
480 strcat (result, "operator");
481 strcat (result, optable[i].out);
482 ret = 1;
483 break;
489 else if (len >= 3
490 && opname[0] == 'o'
491 && opname[1] == 'p'
492 && strchr (cplus_markers, opname[2]) != NULL)
494 /* see if it's an assignment expression */
495 if (len >= 10 /* op$assign_ */
496 && memcmp (opname + 3, "assign_", 7) == 0)
498 size_t i;
499 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
501 len1 = len - 10;
502 if (strlen (optable[i].in) == len1
503 && memcmp (optable[i].in, opname + 10, len1) == 0)
505 strcat (result, "operator");
506 strcat (result, optable[i].out);
507 strcat (result, "=");
508 ret = 1;
509 break;
513 else
515 size_t i;
516 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
518 len1 = len - 3;
519 if (strlen (optable[i].in) == len1
520 && memcmp (optable[i].in, opname + 3, len1) == 0)
522 strcat (result, "operator");
523 strcat (result, optable[i].out);
524 ret = 1;
525 break;
530 else if (len >= 5 && memcmp (opname, "type", 4) == 0
531 && strchr (cplus_markers, opname[4]) != NULL)
533 /* type conversion operator */
534 tem = opname + 5;
535 if (do_type (work, &tem, &type))
537 strcat (result, "operator ");
538 strncat (result, type.b, type.p - type.b);
539 string_delete (&type);
540 ret = 1;
543 squangle_mop_up (work);
544 return ret;
547 /* Takes operator name as e.g. "++" and returns mangled
548 operator name (e.g. "postincrement_expr"), or NULL if not found.
550 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
551 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
553 const char *
554 cplus_mangle_opname (opname, options)
555 const char *opname;
556 int options;
558 size_t i;
559 int len;
561 len = strlen (opname);
562 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
564 if (strlen (optable[i].out) == len
565 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
566 && memcmp (optable[i].out, opname, len) == 0)
567 return optable[i].in;
569 return (0);
572 /* char *cplus_demangle (const char *mangled, int options)
574 If MANGLED is a mangled function name produced by GNU C++, then
575 a pointer to a malloced string giving a C++ representation
576 of the name will be returned; otherwise NULL will be returned.
577 It is the caller's responsibility to free the string which
578 is returned.
580 The OPTIONS arg may contain one or more of the following bits:
582 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
583 included.
584 DMGL_PARAMS Function parameters are included.
586 For example,
588 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
589 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
590 cplus_demangle ("foo__1Ai", 0) => "A::foo"
592 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
593 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
594 cplus_demangle ("foo__1Afe", 0) => "A::foo"
596 Note that any leading underscores, or other such characters prepended by
597 the compilation system, are presumed to have already been stripped from
598 MANGLED. */
600 char *
601 cplus_demangle (mangled, options)
602 const char *mangled;
603 int options;
605 char *ret;
606 struct work_stuff work[1];
607 memset ((char *) work, 0, sizeof (work));
608 work -> options = options;
609 if ((work -> options & DMGL_STYLE_MASK) == 0)
610 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
612 ret = internal_cplus_demangle (work, mangled);
613 squangle_mop_up (work);
614 return (ret);
618 /* This function performs most of what cplus_demangle use to do, but
619 to be able to demangle a name with a B, K or n code, we need to
620 have a longer term memory of what types have been seen. The original
621 now intializes and cleans up the squangle code info, while internal
622 calls go directly to this routine to avoid resetting that info. */
624 static char *
625 internal_cplus_demangle (work, mangled)
626 struct work_stuff *work;
627 const char *mangled;
630 string decl;
631 int success = 0;
632 char *demangled = NULL;
633 int s1,s2,s3,s4;
634 s1 = work->constructor;
635 s2 = work->destructor;
636 s3 = work->static_type;
637 s4 = work->const_type;
638 work->constructor = work->destructor = 0;
639 work->static_type = work->const_type = 0;
641 if ((mangled != NULL) && (*mangled != '\0'))
643 string_init (&decl);
645 /* First check to see if gnu style demangling is active and if the
646 string to be demangled contains a CPLUS_MARKER. If so, attempt to
647 recognize one of the gnu special forms rather than looking for a
648 standard prefix. In particular, don't worry about whether there
649 is a "__" string in the mangled string. Consider "_$_5__foo" for
650 example. */
652 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
654 success = gnu_special (work, &mangled, &decl);
656 if (!success)
658 success = demangle_prefix (work, &mangled, &decl);
660 if (success && (*mangled != '\0'))
662 success = demangle_signature (work, &mangled, &decl);
664 if (work->constructor == 2)
666 string_prepend (&decl, "global constructors keyed to ");
667 work->constructor = 0;
669 else if (work->destructor == 2)
671 string_prepend (&decl, "global destructors keyed to ");
672 work->destructor = 0;
674 demangled = mop_up (work, &decl, success);
676 work->constructor = s1;
677 work->destructor = s2;
678 work->static_type = s3;
679 work->const_type = s4;
680 return (demangled);
684 /* Clear out and squangling related storage */
685 static void
686 squangle_mop_up (work)
687 struct work_stuff *work;
689 /* clean up the B and K type mangling types. */
690 forget_B_and_K_types (work);
691 if (work -> btypevec != NULL)
693 free ((char *) work -> btypevec);
695 if (work -> ktypevec != NULL)
697 free ((char *) work -> ktypevec);
701 /* Clear out any mangled storage */
703 static char *
704 mop_up (work, declp, success)
705 struct work_stuff *work;
706 string *declp;
707 int success;
709 char *demangled = NULL;
711 /* Discard the remembered types, if any. */
713 forget_types (work);
714 if (work -> typevec != NULL)
716 free ((char *) work -> typevec);
717 work -> typevec = NULL;
719 if (work->tmpl_argvec)
721 int i;
723 for (i = 0; i < work->ntmpl_args; i++)
724 if (work->tmpl_argvec[i])
725 free ((char*) work->tmpl_argvec[i]);
727 free ((char*) work->tmpl_argvec);
728 work->tmpl_argvec = NULL;
731 /* If demangling was successful, ensure that the demangled string is null
732 terminated and return it. Otherwise, free the demangling decl. */
734 if (!success)
736 string_delete (declp);
738 else
740 string_appendn (declp, "", 1);
741 demangled = declp -> b;
743 return (demangled);
748 LOCAL FUNCTION
750 demangle_signature -- demangle the signature part of a mangled name
752 SYNOPSIS
754 static int
755 demangle_signature (struct work_stuff *work, const char **mangled,
756 string *declp);
758 DESCRIPTION
760 Consume and demangle the signature portion of the mangled name.
762 DECLP is the string where demangled output is being built. At
763 entry it contains the demangled root name from the mangled name
764 prefix. I.E. either a demangled operator name or the root function
765 name. In some special cases, it may contain nothing.
767 *MANGLED points to the current unconsumed location in the mangled
768 name. As tokens are consumed and demangling is performed, the
769 pointer is updated to continuously point at the next token to
770 be consumed.
772 Demangling GNU style mangled names is nasty because there is no
773 explicit token that marks the start of the outermost function
774 argument list. */
776 static int
777 demangle_signature (work, mangled, declp)
778 struct work_stuff *work;
779 const char **mangled;
780 string *declp;
782 int success = 1;
783 int func_done = 0;
784 int expect_func = 0;
785 int expect_return_type = 0;
786 const char *oldmangled = NULL;
787 string trawname;
788 string tname;
790 while (success && (**mangled != '\0'))
792 switch (**mangled)
794 case 'Q':
795 oldmangled = *mangled;
796 success = demangle_qualified (work, mangled, declp, 1, 0);
797 if (success)
799 remember_type (work, oldmangled, *mangled - oldmangled);
801 if (AUTO_DEMANGLING || GNU_DEMANGLING)
803 expect_func = 1;
805 oldmangled = NULL;
806 break;
808 case 'K':
809 oldmangled = *mangled;
810 success = demangle_qualified (work, mangled, declp, 1, 0);
811 if (AUTO_DEMANGLING || GNU_DEMANGLING)
813 expect_func = 1;
815 oldmangled = NULL;
816 break;
818 case 'S':
819 /* Static member function */
820 if (oldmangled == NULL)
822 oldmangled = *mangled;
824 (*mangled)++;
825 work -> static_type = 1;
826 break;
828 case 'C':
829 /* a const member function */
830 if (oldmangled == NULL)
832 oldmangled = *mangled;
834 (*mangled)++;
835 work -> const_type = 1;
836 break;
838 case '0': case '1': case '2': case '3': case '4':
839 case '5': case '6': case '7': case '8': case '9':
840 if (oldmangled == NULL)
842 oldmangled = *mangled;
844 success = demangle_class (work, mangled, declp);
845 if (success)
847 remember_type (work, oldmangled, *mangled - oldmangled);
849 if (AUTO_DEMANGLING || GNU_DEMANGLING)
851 expect_func = 1;
853 oldmangled = NULL;
854 break;
856 case 'F':
857 /* Function */
858 /* ARM style demangling includes a specific 'F' character after
859 the class name. For GNU style, it is just implied. So we can
860 safely just consume any 'F' at this point and be compatible
861 with either style. */
863 oldmangled = NULL;
864 func_done = 1;
865 (*mangled)++;
867 /* For lucid/ARM style we have to forget any types we might
868 have remembered up to this point, since they were not argument
869 types. GNU style considers all types seen as available for
870 back references. See comment in demangle_args() */
872 if (LUCID_DEMANGLING || ARM_DEMANGLING)
874 forget_types (work);
876 success = demangle_args (work, mangled, declp);
877 break;
879 case 't':
880 /* G++ Template */
881 string_init(&trawname);
882 string_init(&tname);
883 if (oldmangled == NULL)
885 oldmangled = *mangled;
887 success = demangle_template (work, mangled, &tname, &trawname, 1);
888 if (success)
890 remember_type (work, oldmangled, *mangled - oldmangled);
892 string_append(&tname, (work -> options & DMGL_JAVA) ? "." : "::");
893 string_prepends(declp, &tname);
894 if (work -> destructor & 1)
896 string_prepend (&trawname, "~");
897 string_appends (declp, &trawname);
898 work->destructor -= 1;
900 if ((work->constructor & 1) || (work->destructor & 1))
902 string_appends (declp, &trawname);
903 work->constructor -= 1;
905 string_delete(&trawname);
906 string_delete(&tname);
907 oldmangled = NULL;
908 expect_func = 1;
909 break;
911 case '_':
912 if (GNU_DEMANGLING && expect_return_type)
914 /* Read the return type. */
915 string return_type;
916 string_init (&return_type);
918 (*mangled)++;
919 success = do_type (work, mangled, &return_type);
920 APPEND_BLANK (&return_type);
922 string_prepends (declp, &return_type);
923 string_delete (&return_type);
924 break;
926 else
927 /* At the outermost level, we cannot have a return type specified,
928 so if we run into another '_' at this point we are dealing with
929 a mangled name that is either bogus, or has been mangled by
930 some algorithm we don't know how to deal with. So just
931 reject the entire demangling. */
932 success = 0;
933 break;
935 case 'H':
936 if (GNU_DEMANGLING)
938 /* A G++ template function. Read the template arguments. */
939 success = demangle_template (work, mangled, declp, 0, 0);
940 if (!(work->constructor & 1))
941 expect_return_type = 1;
942 (*mangled)++;
943 break;
945 else
946 /* fall through */
949 default:
950 if (AUTO_DEMANGLING || GNU_DEMANGLING)
952 /* Assume we have stumbled onto the first outermost function
953 argument token, and start processing args. */
954 func_done = 1;
955 success = demangle_args (work, mangled, declp);
957 else
959 /* Non-GNU demanglers use a specific token to mark the start
960 of the outermost function argument tokens. Typically 'F',
961 for ARM-demangling, for example. So if we find something
962 we are not prepared for, it must be an error. */
963 success = 0;
965 break;
968 if (AUTO_DEMANGLING || GNU_DEMANGLING)
971 if (success && expect_func)
973 func_done = 1;
974 success = demangle_args (work, mangled, declp);
975 /* Since template include the mangling of their return types,
976 we must set expect_func to 0 so that we don't try do
977 demangle more arguments the next time we get here. */
978 expect_func = 0;
982 if (success && !func_done)
984 if (AUTO_DEMANGLING || GNU_DEMANGLING)
986 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
987 bar__3fooi is 'foo::bar(int)'. We get here when we find the
988 first case, and need to ensure that the '(void)' gets added to
989 the current declp. Note that with ARM, the first case
990 represents the name of a static data member 'foo::bar',
991 which is in the current declp, so we leave it alone. */
992 success = demangle_args (work, mangled, declp);
995 if (success && work -> static_type && PRINT_ARG_TYPES)
997 string_append (declp, " static");
999 if (success && work -> const_type && PRINT_ARG_TYPES)
1001 string_append (declp, " const");
1003 return (success);
1006 #if 0
1008 static int
1009 demangle_method_args (work, mangled, declp)
1010 struct work_stuff *work;
1011 const char **mangled;
1012 string *declp;
1014 int success = 0;
1016 if (work -> static_type)
1018 string_append (declp, *mangled + 1);
1019 *mangled += strlen (*mangled);
1020 success = 1;
1022 else
1024 success = demangle_args (work, mangled, declp);
1026 return (success);
1029 #endif
1031 static int
1032 demangle_template_template_parm (work, mangled, tname)
1033 struct work_stuff *work;
1034 const char **mangled;
1035 string *tname;
1037 int i;
1038 int r;
1039 int need_comma = 0;
1040 int success = 1;
1041 string temp;
1043 string_append (tname, "template <");
1044 /* get size of template parameter list */
1045 if (get_count (mangled, &r))
1047 for (i = 0; i < r; i++)
1049 if (need_comma)
1051 string_append (tname, ", ");
1054 /* Z for type parameters */
1055 if (**mangled == 'Z')
1057 (*mangled)++;
1058 string_append (tname, "class");
1060 /* z for template parameters */
1061 else if (**mangled == 'z')
1063 (*mangled)++;
1064 success =
1065 demangle_template_template_parm (work, mangled, tname);
1066 if (!success)
1068 break;
1071 else
1073 /* temp is initialized in do_type */
1074 success = do_type (work, mangled, &temp);
1075 if (success)
1077 string_appends (tname, &temp);
1079 string_delete(&temp);
1080 if (!success)
1082 break;
1085 need_comma = 1;
1089 if (tname->p[-1] == '>')
1090 string_append (tname, " ");
1091 string_append (tname, "> class");
1092 return (success);
1095 static int
1096 demangle_integral_value (work, mangled, s)
1097 struct work_stuff *work;
1098 const char** mangled;
1099 string* s;
1101 int success;
1103 if (**mangled == 'E')
1105 int need_operator = 0;
1107 success = 1;
1108 string_appendn (s, "(", 1);
1109 (*mangled)++;
1110 while (success && **mangled != 'W' && **mangled != '\0')
1112 if (need_operator)
1114 size_t i;
1115 size_t len;
1117 success = 0;
1119 len = strlen (*mangled);
1121 for (i = 0;
1122 i < sizeof (optable) / sizeof (optable [0]);
1123 ++i)
1125 size_t l = strlen (optable[i].in);
1127 if (l <= len
1128 && memcmp (optable[i].in, *mangled, l) == 0)
1130 string_appendn (s, " ", 1);
1131 string_append (s, optable[i].out);
1132 string_appendn (s, " ", 1);
1133 success = 1;
1134 (*mangled) += l;
1135 break;
1139 if (!success)
1140 break;
1142 else
1143 need_operator = 1;
1145 success = demangle_template_value_parm (work, mangled, s);
1148 if (**mangled != 'W')
1149 success = 0;
1150 else
1152 string_appendn (s, ")", 1);
1153 (*mangled)++;
1156 else if (**mangled == 'Q' || **mangled == 'K')
1157 success = demangle_qualified (work, mangled, s, 0, 1);
1158 else
1160 success = 0;
1162 if (**mangled == 'm')
1164 string_appendn (s, "-", 1);
1165 (*mangled)++;
1167 while (isdigit (**mangled))
1169 string_appendn (s, *mangled, 1);
1170 (*mangled)++;
1171 success = 1;
1175 return success;
1178 static int
1179 demangle_template_value_parm (work, mangled, s)
1180 struct work_stuff *work;
1181 const char **mangled;
1182 string* s;
1184 const char *old_p = *mangled;
1185 int is_pointer = 0;
1186 int is_real = 0;
1187 int is_integral = 0;
1188 int is_char = 0;
1189 int is_bool = 0;
1190 int done = 0;
1191 int success = 1;
1193 while (*old_p && !done)
1195 switch (*old_p)
1197 case 'P':
1198 case 'p':
1199 case 'R':
1200 done = is_pointer = 1;
1201 break;
1202 case 'C': /* const */
1203 case 'S': /* explicitly signed [char] */
1204 case 'U': /* unsigned */
1205 case 'V': /* volatile */
1206 case 'F': /* function */
1207 case 'M': /* member function */
1208 case 'O': /* ??? */
1209 case 'J': /* complex */
1210 old_p++;
1211 continue;
1212 case 'E': /* expression */
1213 case 'Q': /* qualified name */
1214 case 'K': /* qualified name */
1215 done = is_integral = 1;
1216 break;
1217 case 'B': /* squangled name */
1218 done = is_integral = 1;
1219 break;
1220 case 'T': /* remembered type */
1221 abort ();
1222 break;
1223 case 'v': /* void */
1224 abort ();
1225 break;
1226 case 'x': /* long long */
1227 case 'l': /* long */
1228 case 'i': /* int */
1229 case 's': /* short */
1230 case 'w': /* wchar_t */
1231 done = is_integral = 1;
1232 break;
1233 case 'b': /* bool */
1234 done = is_bool = 1;
1235 break;
1236 case 'c': /* char */
1237 done = is_char = 1;
1238 break;
1239 case 'r': /* long double */
1240 case 'd': /* double */
1241 case 'f': /* float */
1242 done = is_real = 1;
1243 break;
1244 default:
1245 /* it's probably user defined type, let's assume
1246 it's integral, it seems hard to figure out
1247 what it really is */
1248 done = is_integral = 1;
1251 if (**mangled == 'Y')
1253 /* The next argument is a template parameter. */
1254 int idx;
1256 (*mangled)++;
1257 idx = consume_count_with_underscores (mangled);
1258 if (idx == -1
1259 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1260 || consume_count_with_underscores (mangled) == -1)
1261 return -1;
1262 if (work->tmpl_argvec)
1263 string_append (s, work->tmpl_argvec[idx]);
1264 else
1266 char buf[10];
1267 sprintf(buf, "T%d", idx);
1268 string_append (s, buf);
1271 else if (is_integral)
1272 success = demangle_integral_value (work, mangled, s);
1273 else if (is_char)
1275 char tmp[2];
1276 int val;
1277 if (**mangled == 'm')
1279 string_appendn (s, "-", 1);
1280 (*mangled)++;
1282 string_appendn (s, "'", 1);
1283 val = consume_count(mangled);
1284 if (val == 0)
1285 return -1;
1286 tmp[0] = (char)val;
1287 tmp[1] = '\0';
1288 string_appendn (s, &tmp[0], 1);
1289 string_appendn (s, "'", 1);
1291 else if (is_bool)
1293 int val = consume_count (mangled);
1294 if (val == 0)
1295 string_appendn (s, "false", 5);
1296 else if (val == 1)
1297 string_appendn (s, "true", 4);
1298 else
1299 success = 0;
1301 else if (is_real)
1303 if (**mangled == 'm')
1305 string_appendn (s, "-", 1);
1306 (*mangled)++;
1308 while (isdigit (**mangled))
1310 string_appendn (s, *mangled, 1);
1311 (*mangled)++;
1313 if (**mangled == '.') /* fraction */
1315 string_appendn (s, ".", 1);
1316 (*mangled)++;
1317 while (isdigit (**mangled))
1319 string_appendn (s, *mangled, 1);
1320 (*mangled)++;
1323 if (**mangled == 'e') /* exponent */
1325 string_appendn (s, "e", 1);
1326 (*mangled)++;
1327 while (isdigit (**mangled))
1329 string_appendn (s, *mangled, 1);
1330 (*mangled)++;
1334 else if (is_pointer)
1336 int symbol_len = consume_count (mangled);
1337 if (symbol_len == 0)
1338 return -1;
1339 if (symbol_len == 0)
1340 string_appendn (s, "0", 1);
1341 else
1343 char *p = xmalloc (symbol_len + 1), *q;
1344 strncpy (p, *mangled, symbol_len);
1345 p [symbol_len] = '\0';
1346 q = internal_cplus_demangle (work, p);
1347 string_appendn (s, "&", 1);
1348 if (q)
1350 string_append (s, q);
1351 free (q);
1353 else
1354 string_append (s, p);
1355 free (p);
1357 *mangled += symbol_len;
1360 return success;
1363 static int
1364 demangle_template (work, mangled, tname, trawname, is_type)
1365 struct work_stuff *work;
1366 const char **mangled;
1367 string *tname;
1368 string *trawname;
1369 int is_type;
1371 int i;
1372 int r;
1373 int need_comma = 0;
1374 int success = 0;
1375 const char *start;
1376 int is_java_array = 0;
1377 string temp;
1379 (*mangled)++;
1380 if (is_type)
1382 start = *mangled;
1383 /* get template name */
1384 if (**mangled == 'z')
1386 int idx;
1387 (*mangled)++;
1388 (*mangled)++;
1390 idx = consume_count_with_underscores (mangled);
1391 if (idx == -1
1392 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1393 || consume_count_with_underscores (mangled) == -1)
1395 return (0);
1397 if (work->tmpl_argvec)
1399 string_append (tname, work->tmpl_argvec[idx]);
1400 if (trawname)
1401 string_append (trawname, work->tmpl_argvec[idx]);
1403 else
1405 char buf[10];
1406 sprintf(buf, "T%d", idx);
1407 string_append (tname, buf);
1408 if (trawname)
1409 string_append (trawname, work->tmpl_argvec[idx]);
1412 else
1414 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
1416 return (0);
1418 if (trawname)
1419 string_appendn (trawname, *mangled, r);
1420 is_java_array = (work -> options & DMGL_JAVA)
1421 && strncmp (*mangled, "JArray1Z", 8) == 0;
1422 if (! is_java_array)
1424 string_appendn (tname, *mangled, r);
1426 *mangled += r;
1429 if (!is_java_array)
1430 string_append (tname, "<");
1431 /* get size of template parameter list */
1432 if (!get_count (mangled, &r))
1434 return (0);
1436 if (!is_type)
1438 /* Create an array for saving the template argument values. */
1439 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1440 work->ntmpl_args = r;
1441 for (i = 0; i < r; i++)
1442 work->tmpl_argvec[i] = 0;
1444 for (i = 0; i < r; i++)
1446 if (need_comma)
1448 string_append (tname, ", ");
1450 /* Z for type parameters */
1451 if (**mangled == 'Z')
1453 (*mangled)++;
1454 /* temp is initialized in do_type */
1455 success = do_type (work, mangled, &temp);
1456 if (success)
1458 string_appends (tname, &temp);
1460 if (!is_type)
1462 /* Save the template argument. */
1463 int len = temp.p - temp.b;
1464 work->tmpl_argvec[i] = xmalloc (len + 1);
1465 memcpy (work->tmpl_argvec[i], temp.b, len);
1466 work->tmpl_argvec[i][len] = '\0';
1469 string_delete(&temp);
1470 if (!success)
1472 break;
1475 /* z for template parameters */
1476 else if (**mangled == 'z')
1478 int r2;
1479 (*mangled)++;
1480 success = demangle_template_template_parm (work, mangled, tname);
1482 if (success
1483 && (r2 = consume_count (mangled)) > 0 && strlen (*mangled) >= r2)
1485 string_append (tname, " ");
1486 string_appendn (tname, *mangled, r2);
1487 if (!is_type)
1489 /* Save the template argument. */
1490 int len = r2;
1491 work->tmpl_argvec[i] = xmalloc (len + 1);
1492 memcpy (work->tmpl_argvec[i], *mangled, len);
1493 work->tmpl_argvec[i][len] = '\0';
1495 *mangled += r2;
1497 if (!success)
1499 break;
1502 else
1504 string param;
1505 string* s;
1507 /* otherwise, value parameter */
1509 /* temp is initialized in do_type */
1510 success = do_type (work, mangled, &temp);
1512 if (success)
1514 string_appends (s, &temp);
1517 string_delete(&temp);
1518 if (!success)
1520 break;
1523 string_append (s, "=");
1526 if (!is_type)
1528 s = &param;
1529 string_init (s);
1531 else
1532 s = tname;
1534 success = demangle_template_value_parm (work, mangled, s);
1536 if (!success)
1538 if (!is_type)
1539 string_delete (s);
1540 success = 0;
1541 break;
1544 if (!is_type)
1546 int len = s->p - s->b;
1547 work->tmpl_argvec[i] = xmalloc (len + 1);
1548 memcpy (work->tmpl_argvec[i], s->b, len);
1549 work->tmpl_argvec[i][len] = '\0';
1551 string_appends (tname, s);
1552 string_delete (s);
1555 need_comma = 1;
1557 if (is_java_array)
1559 string_append (tname, "[]");
1561 else
1563 if (tname->p[-1] == '>')
1564 string_append (tname, " ");
1565 string_append (tname, ">");
1569 if (work -> static_type)
1571 string_append (declp, *mangled + 1);
1572 *mangled += strlen (*mangled);
1573 success = 1;
1575 else
1577 success = demangle_args (work, mangled, declp);
1581 return (success);
1584 static int
1585 arm_pt (work, mangled, n, anchor, args)
1586 struct work_stuff *work;
1587 const char *mangled;
1588 int n;
1589 const char **anchor, **args;
1591 /* ARM template? */
1592 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1594 int len;
1595 *args = *anchor + 6;
1596 len = consume_count (args);
1597 if (*args + len == mangled + n && **args == '_')
1599 ++*args;
1600 return 1;
1603 return 0;
1606 static void
1607 demangle_arm_pt (work, mangled, n, declp)
1608 struct work_stuff *work;
1609 const char **mangled;
1610 int n;
1611 string *declp;
1613 const char *p;
1614 const char *args;
1615 const char *e = *mangled + n;
1617 /* ARM template? */
1618 if (arm_pt (work, *mangled, n, &p, &args))
1620 string arg;
1621 string_init (&arg);
1622 string_appendn (declp, *mangled, p - *mangled);
1623 string_append (declp, "<");
1624 /* should do error checking here */
1625 while (args < e) {
1626 string_clear (&arg);
1627 do_type (work, &args, &arg);
1628 string_appends (declp, &arg);
1629 string_append (declp, ",");
1631 string_delete (&arg);
1632 --declp->p;
1633 string_append (declp, ">");
1635 else
1637 string_appendn (declp, *mangled, n);
1639 *mangled += n;
1642 static int
1643 demangle_class_name (work, mangled, declp)
1644 struct work_stuff *work;
1645 const char **mangled;
1646 string *declp;
1648 int n;
1649 int success = 0;
1651 n = consume_count (mangled);
1652 if (strlen (*mangled) >= n)
1654 demangle_arm_pt (work, mangled, n, declp);
1655 success = 1;
1658 return (success);
1663 LOCAL FUNCTION
1665 demangle_class -- demangle a mangled class sequence
1667 SYNOPSIS
1669 static int
1670 demangle_class (struct work_stuff *work, const char **mangled,
1671 strint *declp)
1673 DESCRIPTION
1675 DECLP points to the buffer into which demangling is being done.
1677 *MANGLED points to the current token to be demangled. On input,
1678 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1679 On exit, it points to the next token after the mangled class on
1680 success, or the first unconsumed token on failure.
1682 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1683 we are demangling a constructor or destructor. In this case
1684 we prepend "class::class" or "class::~class" to DECLP.
1686 Otherwise, we prepend "class::" to the current DECLP.
1688 Reset the constructor/destructor flags once they have been
1689 "consumed". This allows demangle_class to be called later during
1690 the same demangling, to do normal class demangling.
1692 Returns 1 if demangling is successful, 0 otherwise.
1696 static int
1697 demangle_class (work, mangled, declp)
1698 struct work_stuff *work;
1699 const char **mangled;
1700 string *declp;
1702 int success = 0;
1703 int btype;
1704 string class_name;
1706 string_init (&class_name);
1707 btype = register_Btype (work);
1708 if (demangle_class_name (work, mangled, &class_name))
1710 if ((work->constructor & 1) || (work->destructor & 1))
1712 string_prepends (declp, &class_name);
1713 if (work -> destructor & 1)
1715 string_prepend (declp, "~");
1716 work -> destructor -= 1;
1718 else
1720 work -> constructor -= 1;
1723 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
1724 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
1725 string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1726 string_prepends (declp, &class_name);
1727 success = 1;
1729 string_delete (&class_name);
1730 return (success);
1735 LOCAL FUNCTION
1737 demangle_prefix -- consume the mangled name prefix and find signature
1739 SYNOPSIS
1741 static int
1742 demangle_prefix (struct work_stuff *work, const char **mangled,
1743 string *declp);
1745 DESCRIPTION
1747 Consume and demangle the prefix of the mangled name.
1749 DECLP points to the string buffer into which demangled output is
1750 placed. On entry, the buffer is empty. On exit it contains
1751 the root function name, the demangled operator name, or in some
1752 special cases either nothing or the completely demangled result.
1754 MANGLED points to the current pointer into the mangled name. As each
1755 token of the mangled name is consumed, it is updated. Upon entry
1756 the current mangled name pointer points to the first character of
1757 the mangled name. Upon exit, it should point to the first character
1758 of the signature if demangling was successful, or to the first
1759 unconsumed character if demangling of the prefix was unsuccessful.
1761 Returns 1 on success, 0 otherwise.
1764 static int
1765 demangle_prefix (work, mangled, declp)
1766 struct work_stuff *work;
1767 const char **mangled;
1768 string *declp;
1770 int success = 1;
1771 const char *scan;
1772 int i;
1774 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1776 char *marker = strchr (cplus_markers, (*mangled)[8]);
1777 if (marker != NULL && *marker == (*mangled)[10])
1779 if ((*mangled)[9] == 'D')
1781 /* it's a GNU global destructor to be executed at program exit */
1782 (*mangled) += 11;
1783 work->destructor = 2;
1784 if (gnu_special (work, mangled, declp))
1785 return success;
1787 else if ((*mangled)[9] == 'I')
1789 /* it's a GNU global constructor to be executed at program init */
1790 (*mangled) += 11;
1791 work->constructor = 2;
1792 if (gnu_special (work, mangled, declp))
1793 return success;
1797 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1799 /* it's a ARM global destructor to be executed at program exit */
1800 (*mangled) += 7;
1801 work->destructor = 2;
1803 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1805 /* it's a ARM global constructor to be executed at program initial */
1806 (*mangled) += 7;
1807 work->constructor = 2;
1810 /* This block of code is a reduction in strength time optimization
1812 scan = mystrstr (*mangled, "__"); */
1815 scan = *mangled;
1817 do {
1818 scan = strchr (scan, '_');
1819 } while (scan != NULL && *++scan != '_');
1821 if (scan != NULL) --scan;
1824 if (scan != NULL)
1826 /* We found a sequence of two or more '_', ensure that we start at
1827 the last pair in the sequence. */
1828 i = strspn (scan, "_");
1829 if (i > 2)
1831 scan += (i - 2);
1835 if (scan == NULL)
1837 success = 0;
1839 else if (work -> static_type)
1841 if (!isdigit (scan[0]) && (scan[0] != 't'))
1843 success = 0;
1846 else if ((scan == *mangled)
1847 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1848 || (scan[2] == 'K') || (scan[2] == 'H')))
1850 /* The ARM says nothing about the mangling of local variables.
1851 But cfront mangles local variables by prepending __<nesting_level>
1852 to them. As an extension to ARM demangling we handle this case. */
1853 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1855 *mangled = scan + 2;
1856 consume_count (mangled);
1857 string_append (declp, *mangled);
1858 *mangled += strlen (*mangled);
1859 success = 1;
1861 else
1863 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1864 names like __Q2_3foo3bar for nested type names. So don't accept
1865 this style of constructor for cfront demangling. A GNU
1866 style member-template constructor starts with 'H'. */
1867 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1868 work -> constructor += 1;
1869 *mangled = scan + 2;
1872 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1874 /* Mangled name starts with "__". Skip over any leading '_' characters,
1875 then find the next "__" that separates the prefix from the signature.
1877 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1878 || (arm_special (mangled, declp) == 0))
1880 while (*scan == '_')
1882 scan++;
1884 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1886 /* No separator (I.E. "__not_mangled"), or empty signature
1887 (I.E. "__not_mangled_either__") */
1888 success = 0;
1890 else
1892 demangle_function_name (work, mangled, declp, scan);
1896 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1898 /* Cfront-style parameterized type. Handled later as a signature. */
1899 success = 1;
1901 /* ARM template? */
1902 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1904 else if (*(scan + 2) != '\0')
1906 /* Mangled name does not start with "__" but does have one somewhere
1907 in there with non empty stuff after it. Looks like a global
1908 function name. */
1909 demangle_function_name (work, mangled, declp, scan);
1911 else
1913 /* Doesn't look like a mangled name */
1914 success = 0;
1917 if (!success && (work->constructor == 2 || work->destructor == 2))
1919 string_append (declp, *mangled);
1920 *mangled += strlen (*mangled);
1921 success = 1;
1923 return (success);
1928 LOCAL FUNCTION
1930 gnu_special -- special handling of gnu mangled strings
1932 SYNOPSIS
1934 static int
1935 gnu_special (struct work_stuff *work, const char **mangled,
1936 string *declp);
1939 DESCRIPTION
1941 Process some special GNU style mangling forms that don't fit
1942 the normal pattern. For example:
1944 _$_3foo (destructor for class foo)
1945 _vt$foo (foo virtual table)
1946 _vt$foo$bar (foo::bar virtual table)
1947 __vt_foo (foo virtual table, new style with thunks)
1948 _3foo$varname (static data member)
1949 _Q22rs2tu$vw (static data member)
1950 __t6vector1Zii (constructor with template)
1951 __thunk_4__$_7ostream (virtual function thunk)
1954 static int
1955 gnu_special (work, mangled, declp)
1956 struct work_stuff *work;
1957 const char **mangled;
1958 string *declp;
1960 int n;
1961 int success = 1;
1962 const char *p;
1964 if ((*mangled)[0] == '_'
1965 && strchr (cplus_markers, (*mangled)[1]) != NULL
1966 && (*mangled)[2] == '_')
1968 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1969 (*mangled) += 3;
1970 work -> destructor += 1;
1972 else if ((*mangled)[0] == '_'
1973 && (((*mangled)[1] == '_'
1974 && (*mangled)[2] == 'v'
1975 && (*mangled)[3] == 't'
1976 && (*mangled)[4] == '_')
1977 || ((*mangled)[1] == 'v'
1978 && (*mangled)[2] == 't'
1979 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1981 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1982 and create the decl. Note that we consume the entire mangled
1983 input string, which means that demangle_signature has no work
1984 to do. */
1985 if ((*mangled)[2] == 'v')
1986 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1987 else
1988 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1989 while (**mangled != '\0')
1991 p = strpbrk (*mangled, cplus_markers);
1992 switch (**mangled)
1994 case 'Q':
1995 case 'K':
1996 success = demangle_qualified (work, mangled, declp, 0, 1);
1997 break;
1998 case 't':
1999 success = demangle_template (work, mangled, declp, 0, 1);
2000 break;
2001 default:
2002 if (isdigit(*mangled[0]))
2004 n = consume_count(mangled);
2005 /* We may be seeing a too-large size, or else a
2006 ".<digits>" indicating a static local symbol. In
2007 any case, declare victory and move on; *don't* try
2008 to use n to allocate. */
2009 if (n > strlen (*mangled))
2011 success = 1;
2012 break;
2015 else
2017 n = strcspn (*mangled, cplus_markers);
2019 string_appendn (declp, *mangled, n);
2020 (*mangled) += n;
2023 if (success && ((p == NULL) || (p == *mangled)))
2025 if (p != NULL)
2027 string_append (declp,
2028 (work -> options & DMGL_JAVA) ? "." : "::");
2029 (*mangled)++;
2032 else
2034 success = 0;
2035 break;
2038 if (success)
2039 string_append (declp, " virtual table");
2041 else if ((*mangled)[0] == '_'
2042 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2043 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2045 /* static data member, "_3foo$varname" for example */
2046 (*mangled)++;
2047 switch (**mangled)
2049 case 'Q':
2050 case 'K':
2051 success = demangle_qualified (work, mangled, declp, 0, 1);
2052 break;
2053 case 't':
2054 success = demangle_template (work, mangled, declp, 0, 1);
2055 break;
2056 default:
2057 n = consume_count (mangled);
2058 string_appendn (declp, *mangled, n);
2059 (*mangled) += n;
2061 if (success && (p == *mangled))
2063 /* Consumed everything up to the cplus_marker, append the
2064 variable name. */
2065 (*mangled)++;
2066 string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::");
2067 n = strlen (*mangled);
2068 string_appendn (declp, *mangled, n);
2069 (*mangled) += n;
2071 else
2073 success = 0;
2076 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2078 int delta = ((*mangled) += 8, consume_count (mangled));
2079 char *method = internal_cplus_demangle (work, ++*mangled);
2080 if (method)
2082 char buf[50];
2083 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2084 string_append (declp, buf);
2085 string_append (declp, method);
2086 free (method);
2087 n = strlen (*mangled);
2088 (*mangled) += n;
2090 else
2092 success = 0;
2095 else if (strncmp (*mangled, "__t", 3) == 0
2096 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2098 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2099 (*mangled) += 4;
2100 switch (**mangled)
2102 case 'Q':
2103 case 'K':
2104 success = demangle_qualified (work, mangled, declp, 0, 1);
2105 break;
2106 case 't':
2107 success = demangle_template (work, mangled, declp, 0, 1);
2108 break;
2109 default:
2110 success = demangle_fund_type (work, mangled, declp);
2111 break;
2113 if (success && **mangled != '\0')
2114 success = 0;
2115 if (success)
2116 string_append (declp, p);
2118 else
2120 success = 0;
2122 return (success);
2127 LOCAL FUNCTION
2129 arm_special -- special handling of ARM/lucid mangled strings
2131 SYNOPSIS
2133 static int
2134 arm_special (const char **mangled,
2135 string *declp);
2138 DESCRIPTION
2140 Process some special ARM style mangling forms that don't fit
2141 the normal pattern. For example:
2143 __vtbl__3foo (foo virtual table)
2144 __vtbl__3foo__3bar (bar::foo virtual table)
2148 static int
2149 arm_special (mangled, declp)
2150 const char **mangled;
2151 string *declp;
2153 int n;
2154 int success = 1;
2155 const char *scan;
2157 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2159 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2160 and create the decl. Note that we consume the entire mangled
2161 input string, which means that demangle_signature has no work
2162 to do. */
2163 scan = *mangled + ARM_VTABLE_STRLEN;
2164 while (*scan != '\0') /* first check it can be demangled */
2166 n = consume_count (&scan);
2167 if (n==0)
2169 return (0); /* no good */
2171 scan += n;
2172 if (scan[0] == '_' && scan[1] == '_')
2174 scan += 2;
2177 (*mangled) += ARM_VTABLE_STRLEN;
2178 while (**mangled != '\0')
2180 n = consume_count (mangled);
2181 string_prependn (declp, *mangled, n);
2182 (*mangled) += n;
2183 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2185 string_prepend (declp, "::");
2186 (*mangled) += 2;
2189 string_append (declp, " virtual table");
2191 else
2193 success = 0;
2195 return (success);
2200 LOCAL FUNCTION
2202 demangle_qualified -- demangle 'Q' qualified name strings
2204 SYNOPSIS
2206 static int
2207 demangle_qualified (struct work_stuff *, const char *mangled,
2208 string *result, int isfuncname, int append);
2210 DESCRIPTION
2212 Demangle a qualified name, such as "Q25Outer5Inner" which is
2213 the mangled form of "Outer::Inner". The demangled output is
2214 prepended or appended to the result string according to the
2215 state of the append flag.
2217 If isfuncname is nonzero, then the qualified name we are building
2218 is going to be used as a member function name, so if it is a
2219 constructor or destructor function, append an appropriate
2220 constructor or destructor name. I.E. for the above example,
2221 the result for use as a constructor is "Outer::Inner::Inner"
2222 and the result for use as a destructor is "Outer::Inner::~Inner".
2224 BUGS
2226 Numeric conversion is ASCII dependent (FIXME).
2230 static int
2231 demangle_qualified (work, mangled, result, isfuncname, append)
2232 struct work_stuff *work;
2233 const char **mangled;
2234 string *result;
2235 int isfuncname;
2236 int append;
2238 int qualifiers = 0;
2239 int namelength;
2240 int success = 1;
2241 const char *p;
2242 char num[2];
2243 string temp;
2245 string_init (&temp);
2247 if ((*mangled)[0] == 'K')
2249 /* Squangling qualified name reuse */
2250 int idx;
2251 (*mangled)++;
2252 idx = consume_count_with_underscores (mangled);
2253 if (idx == -1 || idx > work -> numk)
2254 success = 0;
2255 else
2256 string_append (&temp, work -> ktypevec[idx]);
2258 else
2259 switch ((*mangled)[1])
2261 case '_':
2262 /* GNU mangled name with more than 9 classes. The count is preceded
2263 by an underscore (to distinguish it from the <= 9 case) and followed
2264 by an underscore. */
2265 p = *mangled + 2;
2266 qualifiers = atoi (p);
2267 if (!isdigit (*p) || *p == '0')
2268 success = 0;
2270 /* Skip the digits. */
2271 while (isdigit (*p))
2272 ++p;
2274 if (*p != '_')
2275 success = 0;
2277 *mangled = p + 1;
2278 break;
2280 case '1':
2281 case '2':
2282 case '3':
2283 case '4':
2284 case '5':
2285 case '6':
2286 case '7':
2287 case '8':
2288 case '9':
2289 /* The count is in a single digit. */
2290 num[0] = (*mangled)[1];
2291 num[1] = '\0';
2292 qualifiers = atoi (num);
2294 /* If there is an underscore after the digit, skip it. This is
2295 said to be for ARM-qualified names, but the ARM makes no
2296 mention of such an underscore. Perhaps cfront uses one. */
2297 if ((*mangled)[2] == '_')
2299 (*mangled)++;
2301 (*mangled) += 2;
2302 break;
2304 case '0':
2305 default:
2306 success = 0;
2309 if (!success)
2310 return success;
2312 /* Pick off the names and collect them in the temp buffer in the order
2313 in which they are found, separated by '::'. */
2315 while (qualifiers-- > 0)
2317 int remember_K = 1;
2318 if (*mangled[0] == '_')
2319 *mangled = *mangled + 1;
2320 if (*mangled[0] == 't')
2322 success = demangle_template(work, mangled, &temp, 0, 1);
2323 if (!success) break;
2325 else if (*mangled[0] == 'X')
2327 success = do_type (work, mangled, &temp);
2328 if (!success) break;
2330 else if (*mangled[0] == 'K')
2332 int idx;
2333 (*mangled)++;
2334 idx = consume_count_with_underscores (mangled);
2335 if (idx == -1 || idx > work->numk)
2336 success = 0;
2337 else
2338 string_append (&temp, work->ktypevec[idx]);
2339 remember_K = 0;
2341 if (!success) break;
2343 else
2345 namelength = consume_count (mangled);
2346 if (strlen (*mangled) < namelength)
2348 /* Simple sanity check failed */
2349 success = 0;
2350 break;
2352 string_appendn (&temp, *mangled, namelength);
2353 *mangled += namelength;
2356 if (remember_K)
2358 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2361 if (qualifiers > 0)
2363 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2367 /* If we are using the result as a function name, we need to append
2368 the appropriate '::' separated constructor or destructor name.
2369 We do this here because this is the most convenient place, where
2370 we already have a pointer to the name and the length of the name. */
2372 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2374 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2375 if (work -> destructor & 1)
2377 string_append (&temp, "~");
2379 string_appendn (&temp, (*mangled) - namelength, namelength);
2382 /* Now either prepend the temp buffer to the result, or append it,
2383 depending upon the state of the append flag. */
2385 if (append)
2387 string_appends (result, &temp);
2389 else
2391 if (!STRING_EMPTY (result))
2393 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2395 string_prepends (result, &temp);
2398 string_delete (&temp);
2399 return (success);
2404 LOCAL FUNCTION
2406 get_count -- convert an ascii count to integer, consuming tokens
2408 SYNOPSIS
2410 static int
2411 get_count (const char **type, int *count)
2413 DESCRIPTION
2415 Return 0 if no conversion is performed, 1 if a string is converted.
2418 static int
2419 get_count (type, count)
2420 const char **type;
2421 int *count;
2423 const char *p;
2424 int n;
2426 if (!isdigit (**type))
2428 return (0);
2430 else
2432 *count = **type - '0';
2433 (*type)++;
2434 if (isdigit (**type))
2436 p = *type;
2437 n = *count;
2440 n *= 10;
2441 n += *p - '0';
2442 p++;
2444 while (isdigit (*p));
2445 if (*p == '_')
2447 *type = p + 1;
2448 *count = n;
2452 return (1);
2455 /* result will be initialised here; it will be freed on failure */
2457 static int
2458 do_type (work, mangled, result)
2459 struct work_stuff *work;
2460 const char **mangled;
2461 string *result;
2463 int n;
2464 int done;
2465 int success;
2466 string decl;
2467 const char *remembered_type;
2468 int constp;
2469 int volatilep;
2470 string btype;
2472 string_init (&btype);
2473 string_init (&decl);
2474 string_init (result);
2476 done = 0;
2477 success = 1;
2478 while (success && !done)
2480 int member;
2481 switch (**mangled)
2484 /* A pointer type */
2485 case 'P':
2486 case 'p':
2487 (*mangled)++;
2488 if (! (work -> options & DMGL_JAVA))
2489 string_prepend (&decl, "*");
2490 break;
2492 /* A reference type */
2493 case 'R':
2494 (*mangled)++;
2495 string_prepend (&decl, "&");
2496 break;
2498 /* An array */
2499 case 'A':
2501 const char *p = ++(*mangled);
2503 string_prepend (&decl, "(");
2504 string_append (&decl, ")[");
2505 /* Copy anything up until the next underscore (the size of the
2506 array). */
2507 while (**mangled && **mangled != '_')
2508 ++(*mangled);
2509 if (**mangled == '_')
2511 string_appendn (&decl, p, *mangled - p);
2512 string_append (&decl, "]");
2513 *mangled += 1;
2515 else
2516 success = 0;
2517 break;
2520 /* A back reference to a previously seen type */
2521 case 'T':
2522 (*mangled)++;
2523 if (!get_count (mangled, &n) || n >= work -> ntypes)
2525 success = 0;
2527 else
2529 remembered_type = work -> typevec[n];
2530 mangled = &remembered_type;
2532 break;
2534 /* A function */
2535 case 'F':
2536 (*mangled)++;
2537 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2539 string_prepend (&decl, "(");
2540 string_append (&decl, ")");
2542 /* After picking off the function args, we expect to either find the
2543 function return type (preceded by an '_') or the end of the
2544 string. */
2545 if (!demangle_args (work, mangled, &decl)
2546 || (**mangled != '_' && **mangled != '\0'))
2548 success = 0;
2550 if (success && (**mangled == '_'))
2552 (*mangled)++;
2554 break;
2556 case 'M':
2557 case 'O':
2559 constp = 0;
2560 volatilep = 0;
2562 member = **mangled == 'M';
2563 (*mangled)++;
2564 if (!isdigit (**mangled) && **mangled != 't')
2566 success = 0;
2567 break;
2570 string_append (&decl, ")");
2571 string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::");
2572 if (isdigit (**mangled))
2574 n = consume_count (mangled);
2575 if (strlen (*mangled) < n)
2577 success = 0;
2578 break;
2580 string_prependn (&decl, *mangled, n);
2581 *mangled += n;
2583 else
2585 string temp;
2586 string_init (&temp);
2587 success = demangle_template (work, mangled, &temp, NULL, 1);
2588 if (success)
2590 string_prependn (&decl, temp.b, temp.p - temp.b);
2591 string_clear (&temp);
2593 else
2594 break;
2596 string_prepend (&decl, "(");
2597 if (member)
2599 if (**mangled == 'C')
2601 (*mangled)++;
2602 constp = 1;
2604 if (**mangled == 'V')
2606 (*mangled)++;
2607 volatilep = 1;
2609 if (*(*mangled)++ != 'F')
2611 success = 0;
2612 break;
2615 if ((member && !demangle_args (work, mangled, &decl))
2616 || **mangled != '_')
2618 success = 0;
2619 break;
2621 (*mangled)++;
2622 if (! PRINT_ANSI_QUALIFIERS)
2624 break;
2626 if (constp)
2628 APPEND_BLANK (&decl);
2629 string_append (&decl, "const");
2631 if (volatilep)
2633 APPEND_BLANK (&decl);
2634 string_append (&decl, "volatile");
2636 break;
2638 case 'G':
2639 (*mangled)++;
2640 break;
2642 case 'C':
2643 case 'V':
2645 if ((*mangled)[1] == 'P')
2648 if (PRINT_ANSI_QUALIFIERS)
2650 if (!STRING_EMPTY (&decl))
2652 string_prepend (&decl, " ");
2654 string_prepend (&decl,
2655 (**mangled) == 'C' ? "const" : "volatile");
2657 (*mangled)++;
2658 break;
2663 /* fall through */
2664 default:
2665 done = 1;
2666 break;
2670 switch (**mangled)
2672 /* A qualified name, such as "Outer::Inner". */
2673 case 'Q':
2674 case 'K':
2676 int btype = register_Btype (work);
2677 success = demangle_qualified (work, mangled, result, 0, 1);
2678 remember_Btype (work, result->b, LEN_STRING (result), btype);
2680 break;
2683 /* A back reference to a previously seen squangled type */
2684 case 'B':
2685 (*mangled)++;
2686 if (!get_count (mangled, &n) || n >= work -> numb)
2687 success = 0;
2688 else
2690 string_append (result, work->btypevec[n]);
2692 break;
2694 case 'X':
2695 case 'Y':
2696 /* A template parm. We substitute the corresponding argument. */
2698 int idx;
2700 (*mangled)++;
2701 idx = consume_count_with_underscores (mangled);
2703 if (idx == -1
2704 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2705 || consume_count_with_underscores (mangled) == -1)
2707 success = 0;
2708 break;
2711 if (work->tmpl_argvec)
2712 string_append (result, work->tmpl_argvec[idx]);
2713 else
2715 char buf[10];
2716 sprintf(buf, "T%d", idx);
2717 string_append (result, buf);
2720 success = 1;
2722 break;
2724 default:
2725 success = demangle_fund_type (work, mangled, result);
2726 break;
2729 if (success)
2731 if (!STRING_EMPTY (&decl))
2733 string_append (result, " ");
2734 string_appends (result, &decl);
2737 else
2739 string_delete (result);
2741 string_delete (&decl);
2742 return (success);
2745 /* Given a pointer to a type string that represents a fundamental type
2746 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2747 string in which the demangled output is being built in RESULT, and
2748 the WORK structure, decode the types and add them to the result.
2750 For example:
2752 "Ci" => "const int"
2753 "Sl" => "signed long"
2754 "CUs" => "const unsigned short"
2758 static int
2759 demangle_fund_type (work, mangled, result)
2760 struct work_stuff *work;
2761 const char **mangled;
2762 string *result;
2764 int done = 0;
2765 int success = 1;
2766 string btype;
2767 string_init (&btype);
2769 /* First pick off any type qualifiers. There can be more than one. */
2771 while (!done)
2773 switch (**mangled)
2775 case 'C':
2776 (*mangled)++;
2777 if (PRINT_ANSI_QUALIFIERS)
2779 APPEND_BLANK (result);
2780 string_append (result, "const");
2782 break;
2783 case 'U':
2784 (*mangled)++;
2785 APPEND_BLANK (result);
2786 string_append (result, "unsigned");
2787 break;
2788 case 'S': /* signed char only */
2789 (*mangled)++;
2790 APPEND_BLANK (result);
2791 string_append (result, "signed");
2792 break;
2793 case 'V':
2794 (*mangled)++;
2795 if (PRINT_ANSI_QUALIFIERS)
2797 APPEND_BLANK (result);
2798 string_append (result, "volatile");
2800 break;
2801 case 'J':
2802 (*mangled)++;
2803 APPEND_BLANK (result);
2804 string_append (result, "__complex");
2805 break;
2806 default:
2807 done = 1;
2808 break;
2812 /* Now pick off the fundamental type. There can be only one. */
2814 switch (**mangled)
2816 case '\0':
2817 case '_':
2818 break;
2819 case 'v':
2820 (*mangled)++;
2821 APPEND_BLANK (result);
2822 string_append (result, "void");
2823 break;
2824 case 'x':
2825 (*mangled)++;
2826 APPEND_BLANK (result);
2827 string_append (result, "long long");
2828 break;
2829 case 'l':
2830 (*mangled)++;
2831 APPEND_BLANK (result);
2832 string_append (result, "long");
2833 break;
2834 case 'i':
2835 (*mangled)++;
2836 APPEND_BLANK (result);
2837 string_append (result, "int");
2838 break;
2839 case 's':
2840 (*mangled)++;
2841 APPEND_BLANK (result);
2842 string_append (result, "short");
2843 break;
2844 case 'b':
2845 (*mangled)++;
2846 APPEND_BLANK (result);
2847 string_append (result, "bool");
2848 break;
2849 case 'c':
2850 (*mangled)++;
2851 APPEND_BLANK (result);
2852 string_append (result, "char");
2853 break;
2854 case 'w':
2855 (*mangled)++;
2856 APPEND_BLANK (result);
2857 string_append (result, "wchar_t");
2858 break;
2859 case 'r':
2860 (*mangled)++;
2861 APPEND_BLANK (result);
2862 string_append (result, "long double");
2863 break;
2864 case 'd':
2865 (*mangled)++;
2866 APPEND_BLANK (result);
2867 string_append (result, "double");
2868 break;
2869 case 'f':
2870 (*mangled)++;
2871 APPEND_BLANK (result);
2872 string_append (result, "float");
2873 break;
2874 case 'G':
2875 (*mangled)++;
2876 if (!isdigit (**mangled))
2878 success = 0;
2879 break;
2881 /* fall through */
2882 /* An explicit type, such as "6mytype" or "7integer" */
2883 case '0':
2884 case '1':
2885 case '2':
2886 case '3':
2887 case '4':
2888 case '5':
2889 case '6':
2890 case '7':
2891 case '8':
2892 case '9':
2894 int bindex = register_Btype (work);
2895 string btype;
2896 string_init (&btype);
2897 if (demangle_class_name (work, mangled, &btype)) {
2898 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
2899 APPEND_BLANK (result);
2900 string_appends (result, &btype);
2902 else
2903 success = 0;
2904 string_delete (&btype);
2905 break;
2907 case 't':
2909 int bindex= register_Btype (work);
2910 success = demangle_template (work, mangled, &btype, 0, 1);
2911 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
2912 string_appends (result, &btype);
2913 break;
2915 default:
2916 success = 0;
2917 break;
2920 return (success);
2923 /* `result' will be initialized in do_type; it will be freed on failure */
2925 static int
2926 do_arg (work, mangled, result)
2927 struct work_stuff *work;
2928 const char **mangled;
2929 string *result;
2931 const char *start = *mangled;
2933 if (!do_type (work, mangled, result))
2935 return (0);
2937 else
2939 remember_type (work, start, *mangled - start);
2940 return (1);
2944 static void
2945 remember_type (work, start, len)
2946 struct work_stuff *work;
2947 const char *start;
2948 int len;
2950 char *tem;
2952 if (work -> ntypes >= work -> typevec_size)
2954 if (work -> typevec_size == 0)
2956 work -> typevec_size = 3;
2957 work -> typevec
2958 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2960 else
2962 work -> typevec_size *= 2;
2963 work -> typevec
2964 = (char **) xrealloc ((char *)work -> typevec,
2965 sizeof (char *) * work -> typevec_size);
2968 tem = xmalloc (len + 1);
2969 memcpy (tem, start, len);
2970 tem[len] = '\0';
2971 work -> typevec[work -> ntypes++] = tem;
2975 /* Remember a K type class qualifier. */
2976 static void
2977 remember_Ktype (work, start, len)
2978 struct work_stuff *work;
2979 const char *start;
2980 int len;
2982 char *tem;
2984 if (work -> numk >= work -> ksize)
2986 if (work -> ksize == 0)
2988 work -> ksize = 5;
2989 work -> ktypevec
2990 = (char **) xmalloc (sizeof (char *) * work -> ksize);
2992 else
2994 work -> ksize *= 2;
2995 work -> ktypevec
2996 = (char **) xrealloc ((char *)work -> ktypevec,
2997 sizeof (char *) * work -> ksize);
3000 tem = xmalloc (len + 1);
3001 memcpy (tem, start, len);
3002 tem[len] = '\0';
3003 work -> ktypevec[work -> numk++] = tem;
3006 /* Register a B code, and get an index for it. B codes are registered
3007 as they are seen, rather than as they are completed, so map<temp<char> >
3008 registers map<temp<char> > as B0, and temp<char> as B1 */
3010 static int
3011 register_Btype (work)
3012 struct work_stuff *work;
3014 int ret;
3016 if (work -> numb >= work -> bsize)
3018 if (work -> bsize == 0)
3020 work -> bsize = 5;
3021 work -> btypevec
3022 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3024 else
3026 work -> bsize *= 2;
3027 work -> btypevec
3028 = (char **) xrealloc ((char *)work -> btypevec,
3029 sizeof (char *) * work -> bsize);
3032 ret = work -> numb++;
3033 work -> btypevec[ret] = NULL;
3034 return(ret);
3037 /* Store a value into a previously registered B code type. */
3039 static void
3040 remember_Btype (work, start, len, index)
3041 struct work_stuff *work;
3042 const char *start;
3043 int len, index;
3045 char *tem;
3047 tem = xmalloc (len + 1);
3048 memcpy (tem, start, len);
3049 tem[len] = '\0';
3050 work -> btypevec[index] = tem;
3053 /* Lose all the info related to B and K type codes. */
3054 static void
3055 forget_B_and_K_types (work)
3056 struct work_stuff *work;
3058 int i;
3060 while (work -> numk > 0)
3062 i = --(work -> numk);
3063 if (work -> ktypevec[i] != NULL)
3065 free (work -> ktypevec[i]);
3066 work -> ktypevec[i] = NULL;
3070 while (work -> numb > 0)
3072 i = --(work -> numb);
3073 if (work -> btypevec[i] != NULL)
3075 free (work -> btypevec[i]);
3076 work -> btypevec[i] = NULL;
3080 /* Forget the remembered types, but not the type vector itself. */
3082 static void
3083 forget_types (work)
3084 struct work_stuff *work;
3086 int i;
3088 while (work -> ntypes > 0)
3090 i = --(work -> ntypes);
3091 if (work -> typevec[i] != NULL)
3093 free (work -> typevec[i]);
3094 work -> typevec[i] = NULL;
3099 /* Process the argument list part of the signature, after any class spec
3100 has been consumed, as well as the first 'F' character (if any). For
3101 example:
3103 "__als__3fooRT0" => process "RT0"
3104 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3106 DECLP must be already initialised, usually non-empty. It won't be freed
3107 on failure.
3109 Note that g++ differs significantly from ARM and lucid style mangling
3110 with regards to references to previously seen types. For example, given
3111 the source fragment:
3113 class foo {
3114 public:
3115 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3118 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3119 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3121 g++ produces the names:
3123 __3fooiRT0iT2iT2
3124 foo__FiR3fooiT1iT1
3126 while lcc (and presumably other ARM style compilers as well) produces:
3128 foo__FiR3fooT1T2T1T2
3129 __ct__3fooFiR3fooT1T2T1T2
3131 Note that g++ bases its type numbers starting at zero and counts all
3132 previously seen types, while lucid/ARM bases its type numbers starting
3133 at one and only considers types after it has seen the 'F' character
3134 indicating the start of the function args. For lucid/ARM style, we
3135 account for this difference by discarding any previously seen types when
3136 we see the 'F' character, and subtracting one from the type number
3137 reference.
3141 static int
3142 demangle_args (work, mangled, declp)
3143 struct work_stuff *work;
3144 const char **mangled;
3145 string *declp;
3147 string arg;
3148 int need_comma = 0;
3149 int r;
3150 int t;
3151 const char *tem;
3152 char temptype;
3154 if (PRINT_ARG_TYPES)
3156 string_append (declp, "(");
3157 if (**mangled == '\0')
3159 string_append (declp, "void");
3163 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3165 if ((**mangled == 'N') || (**mangled == 'T'))
3167 temptype = *(*mangled)++;
3169 if (temptype == 'N')
3171 if (!get_count (mangled, &r))
3173 return (0);
3176 else
3178 r = 1;
3180 if (ARM_DEMANGLING && work -> ntypes >= 10)
3182 /* If we have 10 or more types we might have more than a 1 digit
3183 index so we'll have to consume the whole count here. This
3184 will lose if the next thing is a type name preceded by a
3185 count but it's impossible to demangle that case properly
3186 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3187 Pc, ...)" or "(..., type12, char *, ...)" */
3188 if ((t = consume_count(mangled)) == 0)
3190 return (0);
3193 else
3195 if (!get_count (mangled, &t))
3197 return (0);
3200 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3202 t--;
3204 /* Validate the type index. Protect against illegal indices from
3205 malformed type strings. */
3206 if ((t < 0) || (t >= work -> ntypes))
3208 return (0);
3210 while (--r >= 0)
3212 tem = work -> typevec[t];
3213 if (need_comma && PRINT_ARG_TYPES)
3215 string_append (declp, ", ");
3217 if (!do_arg (work, &tem, &arg))
3219 return (0);
3221 if (PRINT_ARG_TYPES)
3223 string_appends (declp, &arg);
3225 string_delete (&arg);
3226 need_comma = 1;
3229 else
3231 if (need_comma & PRINT_ARG_TYPES)
3233 string_append (declp, ", ");
3235 if (!do_arg (work, mangled, &arg))
3237 return (0);
3239 if (PRINT_ARG_TYPES)
3241 string_appends (declp, &arg);
3243 string_delete (&arg);
3244 need_comma = 1;
3248 if (**mangled == 'e')
3250 (*mangled)++;
3251 if (PRINT_ARG_TYPES)
3253 if (need_comma)
3255 string_append (declp, ",");
3257 string_append (declp, "...");
3261 if (PRINT_ARG_TYPES)
3263 string_append (declp, ")");
3265 return (1);
3268 static void
3269 demangle_function_name (work, mangled, declp, scan)
3270 struct work_stuff *work;
3271 const char **mangled;
3272 string *declp;
3273 const char *scan;
3275 size_t i;
3276 string type;
3277 const char *tem;
3279 string_appendn (declp, (*mangled), scan - (*mangled));
3280 string_need (declp, 1);
3281 *(declp -> p) = '\0';
3283 /* Consume the function name, including the "__" separating the name
3284 from the signature. We are guaranteed that SCAN points to the
3285 separator. */
3287 (*mangled) = scan + 2;
3289 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3292 /* See if we have an ARM style constructor or destructor operator.
3293 If so, then just record it, clear the decl, and return.
3294 We can't build the actual constructor/destructor decl until later,
3295 when we recover the class name from the signature. */
3297 if (strcmp (declp -> b, "__ct") == 0)
3299 work -> constructor += 1;
3300 string_clear (declp);
3301 return;
3303 else if (strcmp (declp -> b, "__dt") == 0)
3305 work -> destructor += 1;
3306 string_clear (declp);
3307 return;
3311 if (declp->p - declp->b >= 3
3312 && declp->b[0] == 'o'
3313 && declp->b[1] == 'p'
3314 && strchr (cplus_markers, declp->b[2]) != NULL)
3316 /* see if it's an assignment expression */
3317 if (declp->p - declp->b >= 10 /* op$assign_ */
3318 && memcmp (declp->b + 3, "assign_", 7) == 0)
3320 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3322 int len = declp->p - declp->b - 10;
3323 if (strlen (optable[i].in) == len
3324 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3326 string_clear (declp);
3327 string_append (declp, "operator");
3328 string_append (declp, optable[i].out);
3329 string_append (declp, "=");
3330 break;
3334 else
3336 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3338 int len = declp->p - declp->b - 3;
3339 if (strlen (optable[i].in) == len
3340 && memcmp (optable[i].in, declp->b + 3, len) == 0)
3342 string_clear (declp);
3343 string_append (declp, "operator");
3344 string_append (declp, optable[i].out);
3345 break;
3350 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3351 && strchr (cplus_markers, declp->b[4]) != NULL)
3353 /* type conversion operator */
3354 tem = declp->b + 5;
3355 if (do_type (work, &tem, &type))
3357 string_clear (declp);
3358 string_append (declp, "operator ");
3359 string_appends (declp, &type);
3360 string_delete (&type);
3363 else if (declp->b[0] == '_' && declp->b[1] == '_'
3364 && declp->b[2] == 'o' && declp->b[3] == 'p')
3366 /* ANSI. */
3367 /* type conversion operator. */
3368 tem = declp->b + 4;
3369 if (do_type (work, &tem, &type))
3371 string_clear (declp);
3372 string_append (declp, "operator ");
3373 string_appends (declp, &type);
3374 string_delete (&type);
3377 else if (declp->b[0] == '_' && declp->b[1] == '_'
3378 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3379 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3381 if (declp->b[4] == '\0')
3383 /* Operator. */
3384 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3386 if (strlen (optable[i].in) == 2
3387 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3389 string_clear (declp);
3390 string_append (declp, "operator");
3391 string_append (declp, optable[i].out);
3392 break;
3396 else
3398 if (declp->b[2] == 'a' && declp->b[5] == '\0')
3400 /* Assignment. */
3401 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3403 if (strlen (optable[i].in) == 3
3404 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3406 string_clear (declp);
3407 string_append (declp, "operator");
3408 string_append (declp, optable[i].out);
3409 break;
3417 /* a mini string-handling package */
3419 static void
3420 string_need (s, n)
3421 string *s;
3422 int n;
3424 int tem;
3426 if (s->b == NULL)
3428 if (n < 32)
3430 n = 32;
3432 s->p = s->b = xmalloc (n);
3433 s->e = s->b + n;
3435 else if (s->e - s->p < n)
3437 tem = s->p - s->b;
3438 n += tem;
3439 n *= 2;
3440 s->b = xrealloc (s->b, n);
3441 s->p = s->b + tem;
3442 s->e = s->b + n;
3446 static void
3447 string_delete (s)
3448 string *s;
3450 if (s->b != NULL)
3452 free (s->b);
3453 s->b = s->e = s->p = NULL;
3457 static void
3458 string_init (s)
3459 string *s;
3461 s->b = s->p = s->e = NULL;
3464 static void
3465 string_clear (s)
3466 string *s;
3468 s->p = s->b;
3471 #if 0
3473 static int
3474 string_empty (s)
3475 string *s;
3477 return (s->b == s->p);
3480 #endif
3482 static void
3483 string_append (p, s)
3484 string *p;
3485 const char *s;
3487 int n;
3488 if (s == NULL || *s == '\0')
3489 return;
3490 n = strlen (s);
3491 string_need (p, n);
3492 memcpy (p->p, s, n);
3493 p->p += n;
3496 static void
3497 string_appends (p, s)
3498 string *p, *s;
3500 int n;
3502 if (s->b != s->p)
3504 n = s->p - s->b;
3505 string_need (p, n);
3506 memcpy (p->p, s->b, n);
3507 p->p += n;
3511 static void
3512 string_appendn (p, s, n)
3513 string *p;
3514 const char *s;
3515 int n;
3517 if (n != 0)
3519 string_need (p, n);
3520 memcpy (p->p, s, n);
3521 p->p += n;
3525 static void
3526 string_prepend (p, s)
3527 string *p;
3528 const char *s;
3530 if (s != NULL && *s != '\0')
3532 string_prependn (p, s, strlen (s));
3536 static void
3537 string_prepends (p, s)
3538 string *p, *s;
3540 if (s->b != s->p)
3542 string_prependn (p, s->b, s->p - s->b);
3546 static void
3547 string_prependn (p, s, n)
3548 string *p;
3549 const char *s;
3550 int n;
3552 char *q;
3554 if (n != 0)
3556 string_need (p, n);
3557 for (q = p->p - 1; q >= p->b; q--)
3559 q[n] = q[0];
3561 memcpy (p->b, s, n);
3562 p->p += n;
3566 /* To generate a standalone demangler program for testing purposes,
3567 just compile and link this file with -DMAIN and libiberty.a. When
3568 run, it demangles each command line arg, or each stdin string, and
3569 prints the result on stdout. */
3571 #ifdef MAIN
3573 #include "getopt.h"
3575 static char *program_name;
3576 static char *program_version = VERSION;
3577 static int flags = DMGL_PARAMS | DMGL_ANSI;
3579 static void demangle_it PARAMS ((char *));
3580 static void usage PARAMS ((FILE *, int));
3581 static void fatal PARAMS ((char *));
3583 static void
3584 demangle_it (mangled_name)
3585 char *mangled_name;
3587 char *result;
3589 result = cplus_demangle (mangled_name, flags);
3590 if (result == NULL)
3592 printf ("%s\n", mangled_name);
3594 else
3596 printf ("%s\n", result);
3597 free (result);
3601 static void
3602 usage (stream, status)
3603 FILE *stream;
3604 int status;
3606 fprintf (stream, "\
3607 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3608 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3609 [--help] [--version] [arg...]\n",
3610 program_name);
3611 exit (status);
3614 #define MBUF_SIZE 32767
3615 char mbuffer[MBUF_SIZE];
3617 /* Defined in the automatically-generated underscore.c. */
3618 extern int prepends_underscore;
3620 int strip_underscore = 0;
3622 static struct option long_options[] = {
3623 {"strip-underscores", no_argument, 0, '_'},
3624 {"format", required_argument, 0, 's'},
3625 {"help", no_argument, 0, 'h'},
3626 {"java", no_argument, 0, 'j'},
3627 {"no-strip-underscores", no_argument, 0, 'n'},
3628 {"version", no_argument, 0, 'v'},
3629 {0, no_argument, 0, 0}
3632 /* More 'friendly' abort that prints the line and file.
3633 config.h can #define abort fancy_abort if you like that sort of thing. */
3635 void
3636 fancy_abort ()
3638 fatal ("Internal gcc abort.");
3642 main (argc, argv)
3643 int argc;
3644 char **argv;
3646 char *result;
3647 int c;
3649 program_name = argv[0];
3651 strip_underscore = prepends_underscore;
3653 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3655 switch (c)
3657 case '?':
3658 usage (stderr, 1);
3659 break;
3660 case 'h':
3661 usage (stdout, 0);
3662 case 'n':
3663 strip_underscore = 0;
3664 break;
3665 case 'v':
3666 printf ("GNU %s version %s\n", program_name, program_version);
3667 exit (0);
3668 case '_':
3669 strip_underscore = 1;
3670 break;
3671 case 'j':
3672 flags |= DMGL_JAVA;
3673 break;
3674 case 's':
3675 if (strcmp (optarg, "gnu") == 0)
3677 current_demangling_style = gnu_demangling;
3679 else if (strcmp (optarg, "lucid") == 0)
3681 current_demangling_style = lucid_demangling;
3683 else if (strcmp (optarg, "arm") == 0)
3685 current_demangling_style = arm_demangling;
3687 else
3689 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3690 program_name, optarg);
3691 exit (1);
3693 break;
3697 if (optind < argc)
3699 for ( ; optind < argc; optind++)
3701 demangle_it (argv[optind]);
3704 else
3706 for (;;)
3708 int i = 0;
3709 c = getchar ();
3710 /* Try to read a label. */
3711 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3713 if (i >= MBUF_SIZE-1)
3714 break;
3715 mbuffer[i++] = c;
3716 c = getchar ();
3718 if (i > 0)
3720 int skip_first = 0;
3722 if (mbuffer[0] == '.')
3723 ++skip_first;
3724 if (strip_underscore && mbuffer[skip_first] == '_')
3725 ++skip_first;
3727 if (skip_first > i)
3728 skip_first = i;
3730 mbuffer[i] = 0;
3732 result = cplus_demangle (mbuffer + skip_first, flags);
3733 if (result)
3735 if (mbuffer[0] == '.')
3736 putc ('.', stdout);
3737 fputs (result, stdout);
3738 free (result);
3740 else
3741 fputs (mbuffer, stdout);
3743 fflush (stdout);
3745 if (c == EOF)
3746 break;
3747 putchar (c);
3751 exit (0);
3754 static void
3755 fatal (str)
3756 char *str;
3758 fprintf (stderr, "%s: %s\n", program_name, str);
3759 exit (1);
3762 char * malloc ();
3763 char * realloc ();
3765 char *
3766 xmalloc (size)
3767 unsigned size;
3769 register char *value = (char *) malloc (size);
3770 if (value == 0)
3771 fatal ("virtual memory exhausted");
3772 return value;
3775 char *
3776 xrealloc (ptr, size)
3777 char *ptr;
3778 unsigned size;
3780 register char *value = (char *) realloc (ptr, size);
3781 if (value == 0)
3782 fatal ("virtual memory exhausted");
3783 return value;
3785 #endif /* main */