* pa.md (alternate dbra pattern): Remove incorrect pattern.
[official-gcc.git] / gcc / cplus-dem.c
blobc7e3ec63bc585252aac9eed61a30ead885390e42
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
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 <string.h>
33 #include <stdio.h>
35 #include <demangle.h>
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 *));
44 static const char *
45 mystrstr (s1, s2)
46 const char *s1, *s2;
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)
55 return (p);
58 return (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 '$'
79 #endif
81 enum demangling_styles current_demangling_style = gnu_demangling;
83 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
85 void
86 set_cplus_marker_for_demangling (ch)
87 int 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. */
95 struct work_stuff
97 int options;
98 char **typevec;
99 int ntypes;
100 int typevec_size;
101 int constructor;
102 int destructor;
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
112 const char *in;
113 const char *out;
114 int flags;
115 } 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 */
202 } string;
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 */
215 static char *
216 mop_up PARAMS ((struct work_stuff *, string *, int));
218 #if 0
219 static int
220 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
221 #endif
223 static int
224 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
225 string *));
227 static int
228 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
229 const char **));
231 static void
232 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
234 static int
235 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
237 static int
238 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
239 int, int));
241 static int
242 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
244 static int
245 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
247 static int
248 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
250 static int
251 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
253 static int
254 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
256 static int
257 arm_special PARAMS ((struct work_stuff *, const char **, string *));
259 static void
260 string_need PARAMS ((string *, int));
262 static void
263 string_delete PARAMS ((string *));
265 static void
266 string_init PARAMS ((string *));
268 static void
269 string_clear PARAMS ((string *));
271 #if 0
272 static int
273 string_empty PARAMS ((string *));
274 #endif
276 static void
277 string_append PARAMS ((string *, const char *));
279 static void
280 string_appends PARAMS ((string *, string *));
282 static void
283 string_appendn PARAMS ((string *, const char *, int));
285 static void
286 string_prepend PARAMS ((string *, const char *));
288 static void
289 string_prependn PARAMS ((string *, const char *, int));
291 static int
292 get_count PARAMS ((const char **, int *));
294 static int
295 consume_count PARAMS ((const char **));
297 static int
298 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
300 static int
301 do_type PARAMS ((struct work_stuff *, const char **, string *));
303 static int
304 do_arg PARAMS ((struct work_stuff *, const char **, string *));
306 static void
307 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
308 const char *));
310 static void
311 remember_type PARAMS ((struct work_stuff *, const char *, int));
313 static void
314 forget_types PARAMS ((struct work_stuff *));
316 static void
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. */
324 static int
325 consume_count (type)
326 const char **type;
328 int count = 0;
330 while (isdigit (**type))
332 count *= 10;
333 count += **type - '0';
334 (*type)++;
336 return (count);
340 cplus_demangle_opname (opname, result, options)
341 const char *opname;
342 char *result;
343 int options;
345 int len, i, len1, ret;
346 string type;
347 struct work_stuff work[1];
348 const char *tem;
350 len = strlen(opname);
351 result[0] = '\0';
352 ret = 0;
353 work->options = options;
355 if (opname[0] == '_' && opname[1] == '_'
356 && opname[2] == 'o' && opname[3] == 'p')
358 /* ANSI. */
359 /* type conversion operator. */
360 tem = opname + 4;
361 if (do_type (work, &tem, &type))
363 strcat (result, "operator ");
364 strncat (result, type.b, type.p - type.b);
365 string_delete (&type);
366 ret = 1;
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')
375 /* Operator. */
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);
383 ret = 1;
384 break;
388 else
390 if (opname[2] == 'a' && opname[5] == '\0')
392 /* Assignment. */
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);
400 ret = 1;
401 break;
407 else if (len >= 3
408 && opname[0] == 'o'
409 && opname[1] == 'p'
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++)
418 len1 = len - 10;
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, "=");
425 ret = 1;
426 break;
430 else
432 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
434 len1 = len - 3;
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);
440 ret = 1;
441 break;
446 else if (len >= 5 && memcmp (opname, "type", 4) == 0
447 && strchr (cplus_markers, opname[4]) != NULL)
449 /* type conversion operator */
450 tem = opname + 5;
451 if (do_type (work, &tem, &type))
453 strcat (result, "operator ");
454 strncat (result, type.b, type.p - type.b);
455 string_delete (&type);
456 ret = 1;
459 return ret;
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. */
468 const char *
469 cplus_mangle_opname (opname, options)
470 const char *opname;
471 int options;
473 int i;
474 int len;
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;
484 return (0);
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
493 is returned.
495 The OPTIONS arg may contain one or more of the following bits:
497 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
498 included.
499 DMGL_PARAMS Function parameters are included.
501 For example,
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
513 MANGLED. */
515 char *
516 cplus_demangle (mangled, options)
517 const char *mangled;
518 int options;
520 string decl;
521 int success = 0;
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;
532 string_init (&decl);
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
539 example. */
541 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
543 success = gnu_special (work, &mangled, &decl);
545 if (!success)
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);
565 return (demangled);
568 static char *
569 mop_up (work, declp, success)
570 struct work_stuff *work;
571 string *declp;
572 int success;
574 char *demangled = NULL;
576 /* Discard the remembered types, if any. */
578 forget_types (work);
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. */
587 if (!success)
589 string_delete (declp);
591 else
593 string_appendn (declp, "", 1);
594 demangled = declp -> b;
596 return (demangled);
601 LOCAL FUNCTION
603 demangle_signature -- demangle the signature part of a mangled name
605 SYNOPSIS
607 static int
608 demangle_signature (struct work_stuff *work, const char **mangled,
609 string *declp);
611 DESCRIPTION
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
623 be consumed.
625 Demangling GNU style mangled names is nasty because there is no
626 explicit token that marks the start of the outermost function
627 argument list. */
629 static int
630 demangle_signature (work, mangled, declp)
631 struct work_stuff *work;
632 const char **mangled;
633 string *declp;
635 int success = 1;
636 int func_done = 0;
637 int expect_func = 0;
638 const char *oldmangled = NULL;
639 string trawname;
640 string tname;
642 while (success && (**mangled != '\0'))
644 switch (**mangled)
646 case 'Q':
647 oldmangled = *mangled;
648 success = demangle_qualified (work, mangled, declp, 1, 0);
649 if (success)
651 remember_type (work, oldmangled, *mangled - oldmangled);
653 if (AUTO_DEMANGLING || GNU_DEMANGLING)
655 expect_func = 1;
657 oldmangled = NULL;
658 break;
660 case 'S':
661 /* Static member function */
662 if (oldmangled == NULL)
664 oldmangled = *mangled;
666 (*mangled)++;
667 work -> static_type = 1;
668 break;
670 case 'C':
671 /* a const member function */
672 if (oldmangled == NULL)
674 oldmangled = *mangled;
676 (*mangled)++;
677 work -> const_type = 1;
678 break;
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);
687 if (success)
689 remember_type (work, oldmangled, *mangled - oldmangled);
691 if (AUTO_DEMANGLING || GNU_DEMANGLING)
693 expect_func = 1;
695 oldmangled = NULL;
696 break;
698 case 'F':
699 /* Function */
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. */
705 oldmangled = NULL;
706 func_done = 1;
707 (*mangled)++;
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)
716 forget_types (work);
718 success = demangle_args (work, mangled, declp);
719 break;
721 case 't':
722 /* G++ Template */
723 string_init(&trawname);
724 string_init(&tname);
725 if (oldmangled == NULL)
727 oldmangled = *mangled;
729 success = demangle_template (work, mangled, &tname, &trawname);
730 if (success)
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);
749 oldmangled = NULL;
750 expect_func = 1;
751 break;
753 case '_':
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. */
759 success = 0;
760 break;
762 default:
763 if (AUTO_DEMANGLING || GNU_DEMANGLING)
765 /* Assume we have stumbled onto the first outermost function
766 argument token, and start processing args. */
767 func_done = 1;
768 success = demangle_args (work, mangled, declp);
770 else
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. */
776 success = 0;
778 break;
781 if (AUTO_DEMANGLING || GNU_DEMANGLING)
784 if (success && expect_func)
786 func_done = 1;
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");
812 return (success);
815 #if 0
817 static int
818 demangle_method_args (work, mangled, declp)
819 struct work_stuff *work;
820 const char **mangled;
821 string *declp;
823 int success = 0;
825 if (work -> static_type)
827 string_append (declp, *mangled + 1);
828 *mangled += strlen (*mangled);
829 success = 1;
831 else
833 success = demangle_args (work, mangled, declp);
835 return (success);
838 #endif
840 static int
841 demangle_template (work, mangled, tname, trawname)
842 struct work_stuff *work;
843 const char **mangled;
844 string *tname;
845 string *trawname;
847 int i;
848 int is_pointer;
849 int is_real;
850 int is_integral;
851 int is_char;
852 int is_bool;
853 int r;
854 int need_comma = 0;
855 int success = 0;
856 int done;
857 const char *old_p;
858 const char *start;
859 int symbol_len;
860 string temp;
862 (*mangled)++;
863 start = *mangled;
864 /* get template name */
865 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
867 return (0);
869 if (trawname)
870 string_appendn (trawname, *mangled, r);
871 string_appendn (tname, *mangled, r);
872 *mangled += r;
873 string_append (tname, "<");
874 /* get size of template parameter list */
875 if (!get_count (mangled, &r))
877 return (0);
879 for (i = 0; i < r; i++)
881 if (need_comma)
883 string_append (tname, ", ");
885 /* Z for type parameters */
886 if (**mangled == 'Z')
888 (*mangled)++;
889 /* temp is initialized in do_type */
890 success = do_type (work, mangled, &temp);
891 if (success)
893 string_appends (tname, &temp);
895 string_delete(&temp);
896 if (!success)
898 break;
901 else
903 /* otherwise, value parameter */
904 old_p = *mangled;
905 is_pointer = 0;
906 is_real = 0;
907 is_integral = 0;
908 is_char = 0;
909 is_bool = 0;
910 done = 0;
911 /* temp is initialized in do_type */
912 success = do_type (work, mangled, &temp);
914 if (success)
916 string_appends (tname, &temp);
919 string_delete(&temp);
920 if (!success)
922 break;
925 string_append (tname, "=");
927 while (*old_p && !done)
929 switch (*old_p)
931 case 'P':
932 case 'p':
933 case 'R':
934 done = is_pointer = 1;
935 break;
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 */
942 case 'O': /* ??? */
943 case 'J': /* complex */
944 old_p++;
945 continue;
946 case 'Q': /* qualified name */
947 done = is_integral = 1;
948 break;
949 case 'T': /* remembered type */
950 abort ();
951 break;
952 case 'v': /* void */
953 abort ();
954 break;
955 case 'x': /* long long */
956 case 'l': /* long */
957 case 'i': /* int */
958 case 's': /* short */
959 case 'w': /* wchar_t */
960 done = is_integral = 1;
961 break;
962 case 'b': /* bool */
963 done = is_bool = 1;
964 break;
965 case 'c': /* char */
966 done = is_char = 1;
967 break;
968 case 'r': /* long double */
969 case 'd': /* double */
970 case 'f': /* float */
971 done = is_real = 1;
972 break;
973 default:
974 /* it's probably user defined type, let's assume
975 it's integral, it seems hard to figure out
976 what it really is */
977 done = is_integral = 1;
980 if (is_integral)
982 if (**mangled == 'm')
984 string_appendn (tname, "-", 1);
985 (*mangled)++;
987 while (isdigit (**mangled))
989 string_appendn (tname, *mangled, 1);
990 (*mangled)++;
993 else if (is_char)
995 char tmp[2];
996 int val;
997 if (**mangled == 'm')
999 string_appendn (tname, "-", 1);
1000 (*mangled)++;
1002 string_appendn (tname, "'", 1);
1003 val = consume_count(mangled);
1004 if (val == 0)
1006 success = 0;
1007 break;
1009 tmp[0] = (char)val;
1010 tmp[1] = '\0';
1011 string_appendn (tname, &tmp[0], 1);
1012 string_appendn (tname, "'", 1);
1014 else if (is_bool)
1016 int val = consume_count (mangled);
1017 if (val == 0)
1018 string_appendn (tname, "false", 5);
1019 else if (val == 1)
1020 string_appendn (tname, "true", 4);
1021 else
1022 success = 0;
1024 else if (is_real)
1026 if (**mangled == 'm')
1028 string_appendn (tname, "-", 1);
1029 (*mangled)++;
1031 while (isdigit (**mangled))
1033 string_appendn (tname, *mangled, 1);
1034 (*mangled)++;
1036 if (**mangled == '.') /* fraction */
1038 string_appendn (tname, ".", 1);
1039 (*mangled)++;
1040 while (isdigit (**mangled))
1042 string_appendn (tname, *mangled, 1);
1043 (*mangled)++;
1046 if (**mangled == 'e') /* exponent */
1048 string_appendn (tname, "e", 1);
1049 (*mangled)++;
1050 while (isdigit (**mangled))
1052 string_appendn (tname, *mangled, 1);
1053 (*mangled)++;
1057 else if (is_pointer)
1059 symbol_len = consume_count (mangled);
1060 if (symbol_len == 0)
1062 success = 0;
1063 break;
1065 if (symbol_len == 0)
1066 string_appendn (tname, "0", 1);
1067 else
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);
1074 if (q)
1076 string_append (tname, q);
1077 free (q);
1079 else
1080 string_append (tname, p);
1081 free (p);
1083 *mangled += symbol_len;
1086 need_comma = 1;
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);
1097 success = 1;
1099 else
1101 success = demangle_args (work, mangled, declp);
1105 return (success);
1108 static int
1109 arm_pt (work, mangled, n, anchor, args)
1110 struct work_stuff *work;
1111 const char *mangled;
1112 int n;
1113 const char **anchor, **args;
1115 /* ARM template? */
1116 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1118 int len;
1119 *args = *anchor + 6;
1120 len = consume_count (args);
1121 if (*args + len == mangled + n && **args == '_')
1123 ++*args;
1124 return 1;
1127 return 0;
1130 static void
1131 demangle_arm_pt (work, mangled, n, declp)
1132 struct work_stuff *work;
1133 const char **mangled;
1134 int n;
1135 string *declp;
1137 const char *p;
1138 const char *args;
1139 const char *e = *mangled + n;
1141 /* ARM template? */
1142 if (arm_pt (work, *mangled, n, &p, &args))
1144 string arg;
1145 string_init (&arg);
1146 string_appendn (declp, *mangled, p - *mangled);
1147 string_append (declp, "<");
1148 /* should do error checking here */
1149 while (args < e) {
1150 string_clear (&arg);
1151 do_type (work, &args, &arg);
1152 string_appends (declp, &arg);
1153 string_append (declp, ",");
1155 string_delete (&arg);
1156 --declp->p;
1157 string_append (declp, ">");
1159 else
1161 string_appendn (declp, *mangled, n);
1163 *mangled += n;
1166 static int
1167 demangle_class_name (work, mangled, declp)
1168 struct work_stuff *work;
1169 const char **mangled;
1170 string *declp;
1172 int n;
1173 int success = 0;
1175 n = consume_count (mangled);
1176 if (strlen (*mangled) >= n)
1178 demangle_arm_pt (work, mangled, n, declp);
1179 success = 1;
1182 return (success);
1187 LOCAL FUNCTION
1189 demangle_class -- demangle a mangled class sequence
1191 SYNOPSIS
1193 static int
1194 demangle_class (struct work_stuff *work, const char **mangled,
1195 strint *declp)
1197 DESCRIPTION
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.
1220 static int
1221 demangle_class (work, mangled, declp)
1222 struct work_stuff *work;
1223 const char **mangled;
1224 string *declp;
1226 int success = 0;
1227 string class_name;
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;
1240 else
1242 work -> constructor -= 1;
1245 string_prepend (declp, "::");
1246 string_prepends (declp, &class_name);
1247 success = 1;
1249 string_delete (&class_name);
1250 return (success);
1255 LOCAL FUNCTION
1257 demangle_prefix -- consume the mangled name prefix and find signature
1259 SYNOPSIS
1261 static int
1262 demangle_prefix (struct work_stuff *work, const char **mangled,
1263 string *declp);
1265 DESCRIPTION
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.
1284 static int
1285 demangle_prefix (work, mangled, declp)
1286 struct work_stuff *work;
1287 const char **mangled;
1288 string *declp;
1290 int success = 1;
1291 const char *scan;
1292 int i;
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 */
1302 (*mangled) += 11;
1303 work->destructor = 2;
1304 if (gnu_special (work, mangled, declp))
1305 return success;
1307 else if ((*mangled)[9] == 'I')
1309 /* it's a GNU global constructor to be executed at program init */
1310 (*mangled) += 11;
1311 work->constructor = 2;
1312 if (gnu_special (work, mangled, declp))
1313 return success;
1317 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1319 /* it's a ARM global destructor to be executed at program exit */
1320 (*mangled) += 7;
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 */
1326 (*mangled) += 7;
1327 work->constructor = 2;
1330 /* This block of code is a reduction in strength time optimization
1332 scan = mystrstr (*mangled, "__"); */
1335 scan = *mangled;
1337 do {
1338 scan = strchr (scan, '_');
1339 } while (scan != NULL && *++scan != '_');
1341 if (scan != NULL) --scan;
1344 if (scan != NULL)
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, "_");
1349 if (i > 2)
1351 scan += (i - 2);
1355 if (scan == NULL)
1357 success = 0;
1359 else if (work -> static_type)
1361 if (!isdigit (scan[0]) && (scan[0] != 't'))
1363 success = 0;
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);
1378 success = 1;
1380 else
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 == '_')
1400 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__") */
1406 success = 0;
1408 else
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. */
1417 success = 1;
1419 /* ARM template? */
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
1426 function name. */
1427 demangle_function_name (work, mangled, declp, scan);
1429 else
1431 /* Doesn't look like a mangled name */
1432 success = 0;
1435 if (!success && (work->constructor == 2 || work->destructor == 2))
1437 string_append (declp, *mangled);
1438 *mangled += strlen (*mangled);
1439 success = 1;
1441 return (success);
1446 LOCAL FUNCTION
1448 gnu_special -- special handling of gnu mangled strings
1450 SYNOPSIS
1452 static int
1453 gnu_special (struct work_stuff *work, const char **mangled,
1454 string *declp);
1457 DESCRIPTION
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)
1472 static int
1473 gnu_special (work, mangled, declp)
1474 struct work_stuff *work;
1475 const char **mangled;
1476 string *declp;
1478 int n;
1479 int success = 1;
1480 const char *p;
1482 if ((*mangled)[0] == '_'
1483 && strchr (cplus_markers, (*mangled)[1]) != NULL
1484 && (*mangled)[2] == '_')
1486 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1487 (*mangled) += 3;
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
1502 to do. */
1503 if ((*mangled)[2] == 'v')
1504 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1505 else
1506 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1507 while (**mangled != '\0')
1509 p = strpbrk (*mangled, cplus_markers);
1510 switch (**mangled)
1512 case 'Q':
1513 success = demangle_qualified (work, mangled, declp, 0, 1);
1514 break;
1515 case 't':
1516 success = demangle_template (work, mangled, declp, 0);
1517 break;
1518 default:
1519 if (isdigit(*mangled[0]))
1521 n = consume_count(mangled);
1523 else
1525 n = strcspn (*mangled, cplus_markers);
1527 string_appendn (declp, *mangled, n);
1528 (*mangled) += n;
1531 if (success && ((p == NULL) || (p == *mangled)))
1533 if (p != NULL)
1535 string_append (declp, "::");
1536 (*mangled)++;
1539 else
1541 success = 0;
1542 break;
1545 if (success)
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 */
1553 (*mangled)++;
1554 switch (**mangled)
1556 case 'Q':
1557 success = demangle_qualified (work, mangled, declp, 0, 1);
1558 break;
1559 case 't':
1560 success = demangle_template (work, mangled, declp, 0);
1561 break;
1562 default:
1563 n = consume_count (mangled);
1564 string_appendn (declp, *mangled, n);
1565 (*mangled) += n;
1567 if (success && (p == *mangled))
1569 /* Consumed everything up to the cplus_marker, append the
1570 variable name. */
1571 (*mangled)++;
1572 string_append (declp, "::");
1573 n = strlen (*mangled);
1574 string_appendn (declp, *mangled, n);
1575 (*mangled) += n;
1577 else
1579 success = 0;
1582 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1584 int delta = ((*mangled) += 8, consume_count (mangled));
1585 char *method = cplus_demangle (++*mangled, work->options);
1586 if (method)
1588 char buf[50];
1589 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1590 string_append (declp, buf);
1591 string_append (declp, method);
1592 free (method);
1593 n = strlen (*mangled);
1594 (*mangled) += n;
1596 else
1598 success = 0;
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";
1605 (*mangled) += 4;
1606 switch (**mangled)
1608 case 'Q':
1609 success = demangle_qualified (work, mangled, declp, 0, 1);
1610 break;
1611 case 't':
1612 success = demangle_template (work, mangled, declp, 0);
1613 break;
1614 default:
1615 success = demangle_fund_type (work, mangled, declp);
1616 break;
1618 if (success && **mangled != '\0')
1619 success = 0;
1620 if (success)
1621 string_append (declp, p);
1623 else
1625 success = 0;
1627 return (success);
1632 LOCAL FUNCTION
1634 arm_special -- special handling of ARM/lucid mangled strings
1636 SYNOPSIS
1638 static int
1639 arm_special (struct work_stuff *work, const char **mangled,
1640 string *declp);
1643 DESCRIPTION
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)
1653 static int
1654 arm_special (work, mangled, declp)
1655 struct work_stuff *work;
1656 const char **mangled;
1657 string *declp;
1659 int n;
1660 int success = 1;
1661 const char *scan;
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
1668 to do. */
1669 scan = *mangled + ARM_VTABLE_STRLEN;
1670 while (*scan != '\0') /* first check it can be demangled */
1672 n = consume_count (&scan);
1673 if (n==0)
1675 return (0); /* no good */
1677 scan += n;
1678 if (scan[0] == '_' && scan[1] == '_')
1680 scan += 2;
1683 (*mangled) += ARM_VTABLE_STRLEN;
1684 while (**mangled != '\0')
1686 n = consume_count (mangled);
1687 string_prependn (declp, *mangled, n);
1688 (*mangled) += n;
1689 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1691 string_prepend (declp, "::");
1692 (*mangled) += 2;
1695 string_append (declp, " virtual table");
1697 else
1699 success = 0;
1701 return (success);
1706 LOCAL FUNCTION
1708 demangle_qualified -- demangle 'Q' qualified name strings
1710 SYNOPSIS
1712 static int
1713 demangle_qualified (struct work_stuff *, const char *mangled,
1714 string *result, int isfuncname, int append);
1716 DESCRIPTION
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".
1730 BUGS
1732 Numeric conversion is ASCII dependent (FIXME).
1736 static int
1737 demangle_qualified (work, mangled, result, isfuncname, append)
1738 struct work_stuff *work;
1739 const char **mangled;
1740 string *result;
1741 int isfuncname;
1742 int append;
1744 int qualifiers;
1745 int namelength;
1746 int success = 1;
1747 const char *p;
1748 char num[2];
1749 string temp;
1751 string_init (&temp);
1752 switch ((*mangled)[1])
1754 case '_':
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. */
1758 p = *mangled + 2;
1759 qualifiers = atoi (p);
1760 if (!isdigit (*p) || *p == '0')
1761 success = 0;
1763 /* Skip the digits. */
1764 while (isdigit (*p))
1765 ++p;
1767 if (*p != '_')
1768 success = 0;
1770 *mangled = p + 1;
1771 break;
1773 case '1':
1774 case '2':
1775 case '3':
1776 case '4':
1777 case '5':
1778 case '6':
1779 case '7':
1780 case '8':
1781 case '9':
1782 /* The count is in a single digit. */
1783 num[0] = (*mangled)[1];
1784 num[1] = '\0';
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] == '_')
1792 (*mangled)++;
1794 (*mangled) += 2;
1795 break;
1797 case '0':
1798 default:
1799 success = 0;
1802 if (!success)
1803 return success;
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;
1817 else
1819 namelength = consume_count (mangled);
1820 if (strlen (*mangled) < namelength)
1822 /* Simple sanity check failed */
1823 success = 0;
1824 break;
1826 string_appendn (&temp, *mangled, namelength);
1827 *mangled += namelength;
1829 if (qualifiers > 0)
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. */
1853 if (append)
1855 string_appends (result, &temp);
1857 else
1859 if (!STRING_EMPTY (result))
1861 string_appendn (&temp, "::", 2);
1863 string_prepends (result, &temp);
1866 string_delete (&temp);
1867 return (success);
1872 LOCAL FUNCTION
1874 get_count -- convert an ascii count to integer, consuming tokens
1876 SYNOPSIS
1878 static int
1879 get_count (const char **type, int *count)
1881 DESCRIPTION
1883 Return 0 if no conversion is performed, 1 if a string is converted.
1886 static int
1887 get_count (type, count)
1888 const char **type;
1889 int *count;
1891 const char *p;
1892 int n;
1894 if (!isdigit (**type))
1896 return (0);
1898 else
1900 *count = **type - '0';
1901 (*type)++;
1902 if (isdigit (**type))
1904 p = *type;
1905 n = *count;
1908 n *= 10;
1909 n += *p - '0';
1910 p++;
1912 while (isdigit (*p));
1913 if (*p == '_')
1915 *type = p + 1;
1916 *count = n;
1920 return (1);
1923 /* result will be initialised here; it will be freed on failure */
1925 static int
1926 do_type (work, mangled, result)
1927 struct work_stuff *work;
1928 const char **mangled;
1929 string *result;
1931 int n;
1932 int done;
1933 int success;
1934 string decl;
1935 const char *remembered_type;
1936 int constp;
1937 int volatilep;
1939 string_init (&decl);
1940 string_init (result);
1942 done = 0;
1943 success = 1;
1944 while (success && !done)
1946 int member;
1947 switch (**mangled)
1950 /* A pointer type */
1951 case 'P':
1952 case 'p':
1953 (*mangled)++;
1954 string_prepend (&decl, "*");
1955 break;
1957 /* A reference type */
1958 case 'R':
1959 (*mangled)++;
1960 string_prepend (&decl, "&");
1961 break;
1963 /* An array */
1964 case 'A':
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
1971 array). */
1972 while (**mangled && **mangled != '_')
1973 ++(*mangled);
1974 if (**mangled == '_')
1976 string_appendn (&decl, p, *mangled - p);
1977 string_append (&decl, "]");
1978 *mangled += 1;
1980 else
1981 success = 0;
1982 break;
1985 /* A back reference to a previously seen type */
1986 case 'T':
1987 (*mangled)++;
1988 if (!get_count (mangled, &n) || n >= work -> ntypes)
1990 success = 0;
1992 else
1994 remembered_type = work -> typevec[n];
1995 mangled = &remembered_type;
1997 break;
1999 /* A function */
2000 case 'F':
2001 (*mangled)++;
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
2009 string. */
2010 if (!demangle_args (work, mangled, &decl)
2011 || (**mangled != '_' && **mangled != '\0'))
2013 success = 0;
2015 if (success && (**mangled == '_'))
2017 (*mangled)++;
2019 break;
2021 case 'M':
2022 case 'O':
2024 constp = 0;
2025 volatilep = 0;
2027 member = **mangled == 'M';
2028 (*mangled)++;
2029 if (!isdigit (**mangled) && **mangled != 't')
2031 success = 0;
2032 break;
2035 string_append (&decl, ")");
2036 string_prepend (&decl, "::");
2037 if (isdigit (**mangled))
2039 n = consume_count (mangled);
2040 if (strlen (*mangled) < n)
2042 success = 0;
2043 break;
2045 string_prependn (&decl, *mangled, n);
2046 *mangled += n;
2048 else
2050 string temp;
2051 string_init (&temp);
2052 success = demangle_template (work, mangled, &temp, NULL);
2053 if (success)
2055 string_prependn (&decl, temp.b, temp.p - temp.b);
2056 string_clear (&temp);
2058 else
2059 break;
2061 string_prepend (&decl, "(");
2062 if (member)
2064 if (**mangled == 'C')
2066 (*mangled)++;
2067 constp = 1;
2069 if (**mangled == 'V')
2071 (*mangled)++;
2072 volatilep = 1;
2074 if (*(*mangled)++ != 'F')
2076 success = 0;
2077 break;
2080 if ((member && !demangle_args (work, mangled, &decl))
2081 || **mangled != '_')
2083 success = 0;
2084 break;
2086 (*mangled)++;
2087 if (! PRINT_ANSI_QUALIFIERS)
2089 break;
2091 if (constp)
2093 APPEND_BLANK (&decl);
2094 string_append (&decl, "const");
2096 if (volatilep)
2098 APPEND_BLANK (&decl);
2099 string_append (&decl, "volatile");
2101 break;
2103 case 'G':
2104 (*mangled)++;
2105 break;
2107 case 'C':
2108 (*mangled)++;
2110 if ((*mangled)[1] == 'P')
2113 if (PRINT_ANSI_QUALIFIERS)
2115 if (!STRING_EMPTY (&decl))
2117 string_prepend (&decl, " ");
2119 string_prepend (&decl, "const");
2121 break;
2126 /* fall through */
2127 default:
2128 done = 1;
2129 break;
2133 switch (**mangled)
2135 /* A qualified name, such as "Outer::Inner". */
2136 case 'Q':
2137 success = demangle_qualified (work, mangled, result, 0, 1);
2138 break;
2140 default:
2141 success = demangle_fund_type (work, mangled, result);
2142 break;
2145 if (success)
2147 if (!STRING_EMPTY (&decl))
2149 string_append (result, " ");
2150 string_appends (result, &decl);
2153 else
2155 string_delete (result);
2157 string_delete (&decl);
2158 return (success);
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.
2166 For example:
2168 "Ci" => "const int"
2169 "Sl" => "signed long"
2170 "CUs" => "const unsigned short"
2174 static int
2175 demangle_fund_type (work, mangled, result)
2176 struct work_stuff *work;
2177 const char **mangled;
2178 string *result;
2180 int done = 0;
2181 int success = 1;
2183 /* First pick off any type qualifiers. There can be more than one. */
2185 while (!done)
2187 switch (**mangled)
2189 case 'C':
2190 (*mangled)++;
2191 if (PRINT_ANSI_QUALIFIERS)
2193 APPEND_BLANK (result);
2194 string_append (result, "const");
2196 break;
2197 case 'U':
2198 (*mangled)++;
2199 APPEND_BLANK (result);
2200 string_append (result, "unsigned");
2201 break;
2202 case 'S': /* signed char only */
2203 (*mangled)++;
2204 APPEND_BLANK (result);
2205 string_append (result, "signed");
2206 break;
2207 case 'V':
2208 (*mangled)++;
2209 if (PRINT_ANSI_QUALIFIERS)
2211 APPEND_BLANK (result);
2212 string_append (result, "volatile");
2214 break;
2215 case 'J':
2216 (*mangled)++;
2217 APPEND_BLANK (result);
2218 string_append (result, "complex");
2219 break;
2220 default:
2221 done = 1;
2222 break;
2226 /* Now pick off the fundamental type. There can be only one. */
2228 switch (**mangled)
2230 case '\0':
2231 case '_':
2232 break;
2233 case 'v':
2234 (*mangled)++;
2235 APPEND_BLANK (result);
2236 string_append (result, "void");
2237 break;
2238 case 'x':
2239 (*mangled)++;
2240 APPEND_BLANK (result);
2241 string_append (result, "long long");
2242 break;
2243 case 'l':
2244 (*mangled)++;
2245 APPEND_BLANK (result);
2246 string_append (result, "long");
2247 break;
2248 case 'i':
2249 (*mangled)++;
2250 APPEND_BLANK (result);
2251 string_append (result, "int");
2252 break;
2253 case 's':
2254 (*mangled)++;
2255 APPEND_BLANK (result);
2256 string_append (result, "short");
2257 break;
2258 case 'b':
2259 (*mangled)++;
2260 APPEND_BLANK (result);
2261 string_append (result, "bool");
2262 break;
2263 case 'c':
2264 (*mangled)++;
2265 APPEND_BLANK (result);
2266 string_append (result, "char");
2267 break;
2268 case 'w':
2269 (*mangled)++;
2270 APPEND_BLANK (result);
2271 string_append (result, "wchar_t");
2272 break;
2273 case 'r':
2274 (*mangled)++;
2275 APPEND_BLANK (result);
2276 string_append (result, "long double");
2277 break;
2278 case 'd':
2279 (*mangled)++;
2280 APPEND_BLANK (result);
2281 string_append (result, "double");
2282 break;
2283 case 'f':
2284 (*mangled)++;
2285 APPEND_BLANK (result);
2286 string_append (result, "float");
2287 break;
2288 case 'G':
2289 (*mangled)++;
2290 if (!isdigit (**mangled))
2292 success = 0;
2293 break;
2295 /* fall through */
2296 /* An explicit type, such as "6mytype" or "7integer" */
2297 case '0':
2298 case '1':
2299 case '2':
2300 case '3':
2301 case '4':
2302 case '5':
2303 case '6':
2304 case '7':
2305 case '8':
2306 case '9':
2307 APPEND_BLANK (result);
2308 if (!demangle_class_name (work, mangled, result)) {
2309 --result->p;
2310 success = 0;
2312 break;
2313 case 't':
2314 success = demangle_template(work,mangled, result, 0);
2315 break;
2316 default:
2317 success = 0;
2318 break;
2321 return (success);
2324 /* `result' will be initialized in do_type; it will be freed on failure */
2326 static int
2327 do_arg (work, mangled, result)
2328 struct work_stuff *work;
2329 const char **mangled;
2330 string *result;
2332 const char *start = *mangled;
2334 if (!do_type (work, mangled, result))
2336 return (0);
2338 else
2340 remember_type (work, start, *mangled - start);
2341 return (1);
2345 static void
2346 remember_type (work, start, len)
2347 struct work_stuff *work;
2348 const char *start;
2349 int len;
2351 char *tem;
2353 if (work -> ntypes >= work -> typevec_size)
2355 if (work -> typevec_size == 0)
2357 work -> typevec_size = 3;
2358 work -> typevec
2359 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2361 else
2363 work -> typevec_size *= 2;
2364 work -> typevec
2365 = (char **) xrealloc ((char *)work -> typevec,
2366 sizeof (char *) * work -> typevec_size);
2369 tem = xmalloc (len + 1);
2370 memcpy (tem, start, len);
2371 tem[len] = '\0';
2372 work -> typevec[work -> ntypes++] = tem;
2375 /* Forget the remembered types, but not the type vector itself. */
2377 static void
2378 forget_types (work)
2379 struct work_stuff *work;
2381 int i;
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
2396 example:
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
2402 on failure.
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:
2408 class foo {
2409 public:
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:
2418 __3fooiRT0iT2iT2
2419 foo__FiR3fooiT1iT1
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
2432 reference.
2436 static int
2437 demangle_args (work, mangled, declp)
2438 struct work_stuff *work;
2439 const char **mangled;
2440 string *declp;
2442 string arg;
2443 int need_comma = 0;
2444 int r;
2445 int t;
2446 const char *tem;
2447 char temptype;
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))
2468 return (0);
2471 else
2473 r = 1;
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)
2485 return (0);
2488 else
2490 if (!get_count (mangled, &t))
2492 return (0);
2495 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2497 t--;
2499 /* Validate the type index. Protect against illegal indices from
2500 malformed type strings. */
2501 if ((t < 0) || (t >= work -> ntypes))
2503 return (0);
2505 while (--r >= 0)
2507 tem = work -> typevec[t];
2508 if (need_comma && PRINT_ARG_TYPES)
2510 string_append (declp, ", ");
2512 if (!do_arg (work, &tem, &arg))
2514 return (0);
2516 if (PRINT_ARG_TYPES)
2518 string_appends (declp, &arg);
2520 string_delete (&arg);
2521 need_comma = 1;
2524 else
2526 if (need_comma & PRINT_ARG_TYPES)
2528 string_append (declp, ", ");
2530 if (!do_arg (work, mangled, &arg))
2532 return (0);
2534 if (PRINT_ARG_TYPES)
2536 string_appends (declp, &arg);
2538 string_delete (&arg);
2539 need_comma = 1;
2543 if (**mangled == 'e')
2545 (*mangled)++;
2546 if (PRINT_ARG_TYPES)
2548 if (need_comma)
2550 string_append (declp, ",");
2552 string_append (declp, "...");
2556 if (PRINT_ARG_TYPES)
2558 string_append (declp, ")");
2560 return (1);
2563 static void
2564 demangle_function_name (work, mangled, declp, scan)
2565 struct work_stuff *work;
2566 const char **mangled;
2567 string *declp;
2568 const char *scan;
2570 int i;
2571 int len;
2572 string type;
2573 const char *tem;
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
2581 separator. */
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);
2597 return;
2599 else if (strcmp (declp -> b, "__dt") == 0)
2601 work -> destructor += 1;
2602 string_clear (declp);
2603 return;
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, "=");
2626 break;
2630 else
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);
2641 break;
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 */
2650 tem = declp->b + 5;
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')
2662 /* ANSI. */
2663 /* type conversion operator. */
2664 tem = declp->b + 4;
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')
2679 /* Operator. */
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);
2688 break;
2692 else
2694 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2696 /* Assignment. */
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);
2705 break;
2713 /* a mini string-handling package */
2715 static void
2716 string_need (s, n)
2717 string *s;
2718 int n;
2720 int tem;
2722 if (s->b == NULL)
2724 if (n < 32)
2726 n = 32;
2728 s->p = s->b = xmalloc (n);
2729 s->e = s->b + n;
2731 else if (s->e - s->p < n)
2733 tem = s->p - s->b;
2734 n += tem;
2735 n *= 2;
2736 s->b = xrealloc (s->b, n);
2737 s->p = s->b + tem;
2738 s->e = s->b + n;
2742 static void
2743 string_delete (s)
2744 string *s;
2746 if (s->b != NULL)
2748 free (s->b);
2749 s->b = s->e = s->p = NULL;
2753 static void
2754 string_init (s)
2755 string *s;
2757 s->b = s->p = s->e = NULL;
2760 static void
2761 string_clear (s)
2762 string *s;
2764 s->p = s->b;
2767 #if 0
2769 static int
2770 string_empty (s)
2771 string *s;
2773 return (s->b == s->p);
2776 #endif
2778 static void
2779 string_append (p, s)
2780 string *p;
2781 const char *s;
2783 int n;
2784 if (s == NULL || *s == '\0')
2785 return;
2786 n = strlen (s);
2787 string_need (p, n);
2788 memcpy (p->p, s, n);
2789 p->p += n;
2792 static void
2793 string_appends (p, s)
2794 string *p, *s;
2796 int n;
2798 if (s->b != s->p)
2800 n = s->p - s->b;
2801 string_need (p, n);
2802 memcpy (p->p, s->b, n);
2803 p->p += n;
2807 static void
2808 string_appendn (p, s, n)
2809 string *p;
2810 const char *s;
2811 int n;
2813 if (n != 0)
2815 string_need (p, n);
2816 memcpy (p->p, s, n);
2817 p->p += n;
2821 static void
2822 string_prepend (p, s)
2823 string *p;
2824 const char *s;
2826 if (s != NULL && *s != '\0')
2828 string_prependn (p, s, strlen (s));
2832 static void
2833 string_prepends (p, s)
2834 string *p, *s;
2836 if (s->b != s->p)
2838 string_prependn (p, s->b, s->p - s->b);
2842 static void
2843 string_prependn (p, s, n)
2844 string *p;
2845 const char *s;
2846 int n;
2848 char *q;
2850 if (n != 0)
2852 string_need (p, n);
2853 for (q = p->p - 1; q >= p->b; q--)
2855 q[n] = q[0];
2857 memcpy (p->b, s, n);
2858 p->p += 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. */
2867 #ifdef MAIN
2869 static void
2870 demangle_it (mangled_name)
2871 char *mangled_name;
2873 char *result;
2875 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2876 if (result == NULL)
2878 printf ("%s\n", mangled_name);
2880 else
2882 printf ("%s\n", result);
2883 free (result);
2887 #include "getopt.h"
2889 static char *program_name;
2890 static char *program_version = VERSION;
2892 static void
2893 usage (stream, status)
2894 FILE *stream;
2895 int status;
2897 fprintf (stream, "\
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",
2901 program_name);
2902 exit (status);
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}
2923 main (argc, argv)
2924 int argc;
2925 char **argv;
2927 char *result;
2928 int c;
2930 program_name = argv[0];
2932 strip_underscore = prepends_underscore;
2934 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2936 switch (c)
2938 case '?':
2939 usage (stderr, 1);
2940 break;
2941 case 'h':
2942 usage (stdout, 0);
2943 case 'n':
2944 strip_underscore = 0;
2945 break;
2946 case 'v':
2947 printf ("GNU %s version %s\n", program_name, program_version);
2948 exit (0);
2949 case '_':
2950 strip_underscore = 1;
2951 break;
2952 case 's':
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;
2965 else
2967 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2968 program_name, optarg);
2969 exit (1);
2971 break;
2975 if (optind < argc)
2977 for ( ; optind < argc; optind++)
2979 demangle_it (argv[optind]);
2982 else
2984 for (;;)
2986 int i = 0;
2987 c = getchar ();
2988 /* Try to read a label. */
2989 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2991 if (i >= MBUF_SIZE-1)
2992 break;
2993 mbuffer[i++] = c;
2994 c = getchar ();
2996 if (i > 0)
2998 int skip_first = 0;
3000 if (mbuffer[0] == '.')
3001 ++skip_first;
3002 if (strip_underscore && mbuffer[skip_first] == '_')
3003 ++skip_first;
3005 if (skip_first > i)
3006 skip_first = i;
3008 mbuffer[i] = 0;
3010 result = cplus_demangle (mbuffer + skip_first,
3011 DMGL_PARAMS | DMGL_ANSI);
3012 if (result)
3014 if (mbuffer[0] == '.')
3015 putc ('.', stdout);
3016 fputs (result, stdout);
3017 free (result);
3019 else
3020 fputs (mbuffer, stdout);
3022 fflush (stdout);
3024 if (c == EOF)
3025 break;
3026 putchar (c);
3030 exit (0);
3033 static void
3034 fatal (str)
3035 char *str;
3037 fprintf (stderr, "%s: %s\n", program_name, str);
3038 exit (1);
3041 char * malloc ();
3042 char * realloc ();
3044 char *
3045 xmalloc (size)
3046 unsigned size;
3048 register char *value = (char *) malloc (size);
3049 if (value == 0)
3050 fatal ("virtual memory exhausted");
3051 return value;
3054 char *
3055 xrealloc (ptr, size)
3056 char *ptr;
3057 unsigned size;
3059 register char *value = (char *) realloc (ptr, size);
3060 if (value == 0)
3061 fatal ("virtual memory exhausted");
3062 return value;
3064 #endif /* main */