(*zeroextract[qs]i_compare0_scratch): Use const_int_operand
[official-gcc.git] / gcc / cplus-dem.c
blob53a668dda5a323e3496e1cdcfe3e2c2d8498c786
1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996 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 #include <ctype.h>
29 #include <string.h>
30 #include <stdio.h>
32 #include <demangle.h>
33 #undef CURRENT_DEMANGLING_STYLE
34 #define CURRENT_DEMANGLING_STYLE work->options
36 extern char *xmalloc PARAMS((unsigned));
37 extern char *xrealloc PARAMS((char *, unsigned));
39 char *
40 mystrstr (s1, s2)
41 char *s1, *s2;
43 register char *p = s1;
44 register int len = strlen (s2);
46 for (; (p = strchr (p, *s2)) != 0; p++)
48 if (strncmp (p, s2, len) == 0)
50 return (p);
53 return (0);
56 /* In order to allow a single demangler executable to demangle strings
57 using various common values of CPLUS_MARKER, as well as any specific
58 one set at compile time, we maintain a string containing all the
59 commonly used ones, and check to see if the marker we are looking for
60 is in that string. CPLUS_MARKER is usually '$' on systems where the
61 assembler can deal with that. Where the assembler can't, it's usually
62 '.' (but on many systems '.' is used for other things). We put the
63 current defined CPLUS_MARKER first (which defaults to '$'), followed
64 by the next most common value, followed by an explicit '$' in case
65 the value of CPLUS_MARKER is not '$'.
67 We could avoid this if we could just get g++ to tell us what the actual
68 cplus marker character is as part of the debug information, perhaps by
69 ensuring that it is the character that terminates the gcc<n>_compiled
70 marker symbol (FIXME). */
72 #if !defined (CPLUS_MARKER)
73 #define CPLUS_MARKER '$'
74 #endif
76 enum demangling_styles current_demangling_style = gnu_demangling;
78 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
80 void
81 set_cplus_marker_for_demangling (ch)
82 int ch;
84 cplus_markers[0] = ch;
87 /* Stuff that is shared between sub-routines.
88 * Using a shared structure allows cplus_demangle to be reentrant. */
90 struct work_stuff
92 int options;
93 char **typevec;
94 int ntypes;
95 int typevec_size;
96 int constructor;
97 int destructor;
98 int static_type; /* A static member function */
99 int const_type; /* A const member function */
102 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
103 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
105 static const struct optable
107 const char *in;
108 const char *out;
109 int flags;
110 } optable[] = {
111 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
112 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
113 {"new", " new", 0}, /* old (1.91, and 1.x) */
114 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
115 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
116 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
117 {"as", "=", DMGL_ANSI}, /* ansi */
118 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
119 {"eq", "==", DMGL_ANSI}, /* old, ansi */
120 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
121 {"gt", ">", DMGL_ANSI}, /* old, ansi */
122 {"le", "<=", DMGL_ANSI}, /* old, ansi */
123 {"lt", "<", DMGL_ANSI}, /* old, ansi */
124 {"plus", "+", 0}, /* old */
125 {"pl", "+", DMGL_ANSI}, /* ansi */
126 {"apl", "+=", DMGL_ANSI}, /* ansi */
127 {"minus", "-", 0}, /* old */
128 {"mi", "-", DMGL_ANSI}, /* ansi */
129 {"ami", "-=", DMGL_ANSI}, /* ansi */
130 {"mult", "*", 0}, /* old */
131 {"ml", "*", DMGL_ANSI}, /* ansi */
132 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
133 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
134 {"convert", "+", 0}, /* old (unary +) */
135 {"negate", "-", 0}, /* old (unary -) */
136 {"trunc_mod", "%", 0}, /* old */
137 {"md", "%", DMGL_ANSI}, /* ansi */
138 {"amd", "%=", DMGL_ANSI}, /* ansi */
139 {"trunc_div", "/", 0}, /* old */
140 {"dv", "/", DMGL_ANSI}, /* ansi */
141 {"adv", "/=", DMGL_ANSI}, /* ansi */
142 {"truth_andif", "&&", 0}, /* old */
143 {"aa", "&&", DMGL_ANSI}, /* ansi */
144 {"truth_orif", "||", 0}, /* old */
145 {"oo", "||", DMGL_ANSI}, /* ansi */
146 {"truth_not", "!", 0}, /* old */
147 {"nt", "!", DMGL_ANSI}, /* ansi */
148 {"postincrement","++", 0}, /* old */
149 {"pp", "++", DMGL_ANSI}, /* ansi */
150 {"postdecrement","--", 0}, /* old */
151 {"mm", "--", DMGL_ANSI}, /* ansi */
152 {"bit_ior", "|", 0}, /* old */
153 {"or", "|", DMGL_ANSI}, /* ansi */
154 {"aor", "|=", DMGL_ANSI}, /* ansi */
155 {"bit_xor", "^", 0}, /* old */
156 {"er", "^", DMGL_ANSI}, /* ansi */
157 {"aer", "^=", DMGL_ANSI}, /* ansi */
158 {"bit_and", "&", 0}, /* old */
159 {"ad", "&", DMGL_ANSI}, /* ansi */
160 {"aad", "&=", DMGL_ANSI}, /* ansi */
161 {"bit_not", "~", 0}, /* old */
162 {"co", "~", DMGL_ANSI}, /* ansi */
163 {"call", "()", 0}, /* old */
164 {"cl", "()", DMGL_ANSI}, /* ansi */
165 {"alshift", "<<", 0}, /* old */
166 {"ls", "<<", DMGL_ANSI}, /* ansi */
167 {"als", "<<=", DMGL_ANSI}, /* ansi */
168 {"arshift", ">>", 0}, /* old */
169 {"rs", ">>", DMGL_ANSI}, /* ansi */
170 {"ars", ">>=", DMGL_ANSI}, /* ansi */
171 {"component", "->", 0}, /* old */
172 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
173 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
174 {"indirect", "*", 0}, /* old */
175 {"method_call", "->()", 0}, /* old */
176 {"addr", "&", 0}, /* old (unary &) */
177 {"array", "[]", 0}, /* old */
178 {"vc", "[]", DMGL_ANSI}, /* ansi */
179 {"compound", ", ", 0}, /* old */
180 {"cm", ", ", DMGL_ANSI}, /* ansi */
181 {"cond", "?:", 0}, /* old */
182 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
183 {"max", ">?", 0}, /* old */
184 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
185 {"min", "<?", 0}, /* old */
186 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
187 {"nop", "", 0}, /* old (for operator=) */
188 {"rm", "->*", DMGL_ANSI} /* ansi */
192 typedef struct string /* Beware: these aren't required to be */
193 { /* '\0' terminated. */
194 char *b; /* pointer to start of string */
195 char *p; /* pointer after last character */
196 char *e; /* pointer after end of allocated space */
197 } string;
199 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
200 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
201 string_prepend(str, " ");}
202 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
203 string_append(str, " ");}
205 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
206 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
208 /* Prototypes for local functions */
210 static char *
211 mop_up PARAMS ((struct work_stuff *, string *, int));
213 #if 0
214 static int
215 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
216 #endif
218 static int
219 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
220 string *));
222 static int
223 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
224 int, int));
226 static int
227 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
229 static int
230 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
232 static int
233 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
235 static int
236 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
238 static int
239 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
241 static int
242 arm_special PARAMS ((struct work_stuff *, const char **, string *));
244 static void
245 string_need PARAMS ((string *, int));
247 static void
248 string_delete PARAMS ((string *));
250 static void
251 string_init PARAMS ((string *));
253 static void
254 string_clear PARAMS ((string *));
256 #if 0
257 static int
258 string_empty PARAMS ((string *));
259 #endif
261 static void
262 string_append PARAMS ((string *, const char *));
264 static void
265 string_appends PARAMS ((string *, string *));
267 static void
268 string_appendn PARAMS ((string *, const char *, int));
270 static void
271 string_prepend PARAMS ((string *, const char *));
273 static void
274 string_prependn PARAMS ((string *, const char *, int));
276 static int
277 get_count PARAMS ((const char **, int *));
279 static int
280 consume_count PARAMS ((const char **));
282 static int
283 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
285 static int
286 do_type PARAMS ((struct work_stuff *, const char **, string *));
288 static int
289 do_arg PARAMS ((struct work_stuff *, const char **, string *));
291 static void
292 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
293 const char *));
295 static void
296 remember_type PARAMS ((struct work_stuff *, const char *, int));
298 static void
299 forget_types PARAMS ((struct work_stuff *));
301 static void
302 string_prepends PARAMS ((string *, string *));
304 /* Translate count to integer, consuming tokens in the process.
305 Conversion terminates on the first non-digit character.
306 Trying to consume something that isn't a count results in
307 no consumption of input and a return of 0. */
309 static int
310 consume_count (type)
311 const char **type;
313 int count = 0;
315 while (isdigit (**type))
317 count *= 10;
318 count += **type - '0';
319 (*type)++;
321 return (count);
325 cplus_demangle_opname (opname, result, options)
326 const char *opname;
327 char *result;
328 int options;
330 int len, i, len1, ret;
331 string type;
332 struct work_stuff work[1];
333 const char *tem;
335 len = strlen(opname);
336 result[0] = '\0';
337 ret = 0;
338 work->options = options;
340 if (opname[0] == '_' && opname[1] == '_'
341 && opname[2] == 'o' && opname[3] == 'p')
343 /* ANSI. */
344 /* type conversion operator. */
345 tem = opname + 4;
346 if (do_type (work, &tem, &type))
348 strcat (result, "operator ");
349 strncat (result, type.b, type.p - type.b);
350 string_delete (&type);
351 ret = 1;
354 else if (opname[0] == '_' && opname[1] == '_'
355 && opname[2] >= 'a' && opname[2] <= 'z'
356 && opname[3] >= 'a' && opname[3] <= 'z')
358 if (opname[4] == '\0')
360 /* Operator. */
361 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
363 if (strlen (optable[i].in) == 2
364 && memcmp (optable[i].in, opname + 2, 2) == 0)
366 strcat (result, "operator");
367 strcat (result, optable[i].out);
368 ret = 1;
369 break;
373 else
375 if (opname[2] == 'a' && opname[5] == '\0')
377 /* Assignment. */
378 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
380 if (strlen (optable[i].in) == 3
381 && memcmp (optable[i].in, opname + 2, 3) == 0)
383 strcat (result, "operator");
384 strcat (result, optable[i].out);
385 ret = 1;
386 break;
392 else if (len >= 3
393 && opname[0] == 'o'
394 && opname[1] == 'p'
395 && strchr (cplus_markers, opname[2]) != NULL)
397 /* see if it's an assignment expression */
398 if (len >= 10 /* op$assign_ */
399 && memcmp (opname + 3, "assign_", 7) == 0)
401 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
403 len1 = len - 10;
404 if (strlen (optable[i].in) == len1
405 && memcmp (optable[i].in, opname + 10, len1) == 0)
407 strcat (result, "operator");
408 strcat (result, optable[i].out);
409 strcat (result, "=");
410 ret = 1;
411 break;
415 else
417 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
419 len1 = len - 3;
420 if (strlen (optable[i].in) == len1
421 && memcmp (optable[i].in, opname + 3, len1) == 0)
423 strcat (result, "operator");
424 strcat (result, optable[i].out);
425 ret = 1;
426 break;
431 else if (len >= 5 && memcmp (opname, "type", 4) == 0
432 && strchr (cplus_markers, opname[4]) != NULL)
434 /* type conversion operator */
435 tem = opname + 5;
436 if (do_type (work, &tem, &type))
438 strcat (result, "operator ");
439 strncat (result, type.b, type.p - type.b);
440 string_delete (&type);
441 ret = 1;
444 return ret;
447 /* Takes operator name as e.g. "++" and returns mangled
448 operator name (e.g. "postincrement_expr"), or NULL if not found.
450 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
451 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
453 const char *
454 cplus_mangle_opname (opname, options)
455 const char *opname;
456 int options;
458 int i;
459 int len;
461 len = strlen (opname);
462 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
464 if (strlen (optable[i].out) == len
465 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
466 && memcmp (optable[i].out, opname, len) == 0)
467 return optable[i].in;
469 return (0);
472 /* check to see whether MANGLED can match TEXT in the first TEXT_LEN
473 characters. */
475 int cplus_match (mangled, text, text_len)
476 const char *mangled;
477 char *text;
478 int text_len;
480 if (strncmp (mangled, text, text_len) != 0) {
481 return(0); /* cannot match either */
482 } else {
483 return(1); /* matches mangled, may match demangled */
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.
630 static int
631 demangle_signature (work, mangled, declp)
632 struct work_stuff *work;
633 const char **mangled;
634 string *declp;
636 int success = 1;
637 int func_done = 0;
638 int expect_func = 0;
639 const char *oldmangled = NULL;
640 string trawname;
641 string tname;
643 while (success && (**mangled != '\0'))
645 switch (**mangled)
647 case 'Q':
648 oldmangled = *mangled;
649 success = demangle_qualified (work, mangled, declp, 1, 0);
650 if (success)
652 remember_type (work, oldmangled, *mangled - oldmangled);
654 if (AUTO_DEMANGLING || GNU_DEMANGLING)
656 expect_func = 1;
658 oldmangled = NULL;
659 break;
661 case 'S':
662 /* Static member function */
663 if (oldmangled == NULL)
665 oldmangled = *mangled;
667 (*mangled)++;
668 work -> static_type = 1;
669 break;
671 case 'C':
672 /* a const member function */
673 if (oldmangled == NULL)
675 oldmangled = *mangled;
677 (*mangled)++;
678 work -> const_type = 1;
679 break;
681 case '0': case '1': case '2': case '3': case '4':
682 case '5': case '6': case '7': case '8': case '9':
683 if (oldmangled == NULL)
685 oldmangled = *mangled;
687 success = demangle_class (work, mangled, declp);
688 if (success)
690 remember_type (work, oldmangled, *mangled - oldmangled);
692 if (AUTO_DEMANGLING || GNU_DEMANGLING)
694 expect_func = 1;
696 oldmangled = NULL;
697 break;
699 case 'F':
700 /* Function */
701 /* ARM style demangling includes a specific 'F' character after
702 the class name. For GNU style, it is just implied. So we can
703 safely just consume any 'F' at this point and be compatible
704 with either style. */
706 oldmangled = NULL;
707 func_done = 1;
708 (*mangled)++;
710 /* For lucid/ARM style we have to forget any types we might
711 have remembered up to this point, since they were not argument
712 types. GNU style considers all types seen as available for
713 back references. See comment in demangle_args() */
715 if (LUCID_DEMANGLING || ARM_DEMANGLING)
717 forget_types (work);
719 success = demangle_args (work, mangled, declp);
720 break;
722 case 't':
723 /* G++ Template */
724 string_init(&trawname);
725 string_init(&tname);
726 if (oldmangled == NULL)
728 oldmangled = *mangled;
730 success = demangle_template (work, mangled, &tname, &trawname);
731 if (success)
733 remember_type (work, oldmangled, *mangled - oldmangled);
735 string_append(&tname, "::");
736 string_prepends(declp, &tname);
737 if (work -> destructor & 1)
739 string_prepend (&trawname, "~");
740 string_appends (declp, &trawname);
741 work->destructor -= 1;
743 if ((work->constructor & 1) || (work->destructor & 1))
745 string_appends (declp, &trawname);
746 work->constructor -= 1;
748 string_delete(&trawname);
749 string_delete(&tname);
750 oldmangled = NULL;
751 expect_func = 1;
752 break;
754 case '_':
755 /* At the outermost level, we cannot have a return type specified,
756 so if we run into another '_' at this point we are dealing with
757 a mangled name that is either bogus, or has been mangled by
758 some algorithm we don't know how to deal with. So just
759 reject the entire demangling. */
760 success = 0;
761 break;
763 default:
764 if (AUTO_DEMANGLING || GNU_DEMANGLING)
766 /* Assume we have stumbled onto the first outermost function
767 argument token, and start processing args. */
768 func_done = 1;
769 success = demangle_args (work, mangled, declp);
771 else
773 /* Non-GNU demanglers use a specific token to mark the start
774 of the outermost function argument tokens. Typically 'F',
775 for ARM-demangling, for example. So if we find something
776 we are not prepared for, it must be an error. */
777 success = 0;
779 break;
782 if (AUTO_DEMANGLING || GNU_DEMANGLING)
785 if (success && expect_func)
787 func_done = 1;
788 success = demangle_args (work, mangled, declp);
792 if (success && !func_done)
794 if (AUTO_DEMANGLING || GNU_DEMANGLING)
796 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
797 bar__3fooi is 'foo::bar(int)'. We get here when we find the
798 first case, and need to ensure that the '(void)' gets added to
799 the current declp. Note that with ARM, the first case
800 represents the name of a static data member 'foo::bar',
801 which is in the current declp, so we leave it alone. */
802 success = demangle_args (work, mangled, declp);
805 if (success && work -> static_type && PRINT_ARG_TYPES)
807 string_append (declp, " static");
809 if (success && work -> const_type && PRINT_ARG_TYPES)
811 string_append (declp, " const");
813 return (success);
816 #if 0
818 static int
819 demangle_method_args (work, mangled, declp)
820 struct work_stuff *work;
821 const char **mangled;
822 string *declp;
824 int success = 0;
826 if (work -> static_type)
828 string_append (declp, *mangled + 1);
829 *mangled += strlen (*mangled);
830 success = 1;
832 else
834 success = demangle_args (work, mangled, declp);
836 return (success);
839 #endif
841 static int
842 demangle_template (work, mangled, tname, trawname)
843 struct work_stuff *work;
844 const char **mangled;
845 string *tname;
846 string *trawname;
848 int i;
849 int is_pointer;
850 int is_real;
851 int is_integral;
852 int is_char;
853 int is_bool;
854 int r;
855 int need_comma = 0;
856 int success = 0;
857 int done;
858 const char *old_p;
859 const char *start;
860 int symbol_len;
861 string temp;
863 (*mangled)++;
864 start = *mangled;
865 /* get template name */
866 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
868 return (0);
870 if (trawname)
871 string_appendn (trawname, *mangled, r);
872 string_appendn (tname, *mangled, r);
873 *mangled += r;
874 string_append (tname, "<");
875 /* get size of template parameter list */
876 if (!get_count (mangled, &r))
878 return (0);
880 for (i = 0; i < r; i++)
882 if (need_comma)
884 string_append (tname, ", ");
886 /* Z for type parameters */
887 if (**mangled == 'Z')
889 (*mangled)++;
890 /* temp is initialized in do_type */
891 success = do_type (work, mangled, &temp);
892 if (success)
894 string_appends (tname, &temp);
896 string_delete(&temp);
897 if (!success)
899 break;
902 else
904 /* otherwise, value parameter */
905 old_p = *mangled;
906 is_pointer = 0;
907 is_real = 0;
908 is_integral = 0;
909 is_char = 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 old_p++;
944 continue;
945 case 'Q': /* qualified name */
946 done = is_integral = 1;
947 break;
948 case 'T': /* remembered type */
949 abort ();
950 break;
951 case 'v': /* void */
952 abort ();
953 break;
954 case 'x': /* long long */
955 case 'l': /* long */
956 case 'i': /* int */
957 case 's': /* short */
958 case 'w': /* wchar_t */
959 done = is_integral = 1;
960 break;
961 case 'b': /* bool */
962 done = is_bool = 1;
963 break;
964 case 'c': /* char */
965 done = is_char = 1;
966 break;
967 case 'r': /* long double */
968 case 'd': /* double */
969 case 'f': /* float */
970 done = is_real = 1;
971 break;
972 default:
973 /* it's probably user defined type, let's assume
974 it's integral, it seems hard to figure out
975 what it really is */
976 done = is_integral = 1;
979 if (is_integral)
981 if (**mangled == 'm')
983 string_appendn (tname, "-", 1);
984 (*mangled)++;
986 while (isdigit (**mangled))
988 string_appendn (tname, *mangled, 1);
989 (*mangled)++;
992 else if (is_char)
994 char tmp[2];
995 int val;
996 if (**mangled == 'm')
998 string_appendn (tname, "-", 1);
999 (*mangled)++;
1001 string_appendn (tname, "'", 1);
1002 val = consume_count(mangled);
1003 if (val == 0)
1005 success = 0;
1006 break;
1008 tmp[0] = (char)val;
1009 tmp[1] = '\0';
1010 string_appendn (tname, &tmp[0], 1);
1011 string_appendn (tname, "'", 1);
1013 else if (is_bool)
1015 int val = consume_count (mangled);
1016 if (val == 0)
1017 string_appendn (tname, "false", 5);
1018 else if (val == 1)
1019 string_appendn (tname, "true", 4);
1020 else
1021 success = 0;
1023 else if (is_real)
1025 if (**mangled == 'm')
1027 string_appendn (tname, "-", 1);
1028 (*mangled)++;
1030 while (isdigit (**mangled))
1032 string_appendn (tname, *mangled, 1);
1033 (*mangled)++;
1035 if (**mangled == '.') /* fraction */
1037 string_appendn (tname, ".", 1);
1038 (*mangled)++;
1039 while (isdigit (**mangled))
1041 string_appendn (tname, *mangled, 1);
1042 (*mangled)++;
1045 if (**mangled == 'e') /* exponent */
1047 string_appendn (tname, "e", 1);
1048 (*mangled)++;
1049 while (isdigit (**mangled))
1051 string_appendn (tname, *mangled, 1);
1052 (*mangled)++;
1056 else if (is_pointer)
1058 if (!get_count (mangled, &symbol_len))
1060 success = 0;
1061 break;
1063 string_appendn (tname, *mangled, symbol_len);
1064 *mangled += symbol_len;
1067 need_comma = 1;
1069 if (tname->p[-1] == '>')
1070 string_append (tname, " ");
1071 string_append (tname, ">");
1074 if (work -> static_type)
1076 string_append (declp, *mangled + 1);
1077 *mangled += strlen (*mangled);
1078 success = 1;
1080 else
1082 success = demangle_args (work, mangled, declp);
1086 return (success);
1089 static int
1090 arm_pt (work, mangled, n, anchor, args)
1091 struct work_stuff *work;
1092 const char *mangled;
1093 int n;
1094 const char **anchor, **args;
1096 /* ARM template? */
1097 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1099 int len;
1100 *args = *anchor + 6;
1101 len = consume_count (args);
1102 if (*args + len == mangled + n && **args == '_')
1104 ++*args;
1105 return 1;
1108 return 0;
1111 static void
1112 demangle_arm_pt (work, mangled, n, declp)
1113 struct work_stuff *work;
1114 const char **mangled;
1115 int n;
1116 string *declp;
1118 const char *p;
1119 const char *args;
1120 const char *e = *mangled + n;
1122 /* ARM template? */
1123 if (arm_pt (work, *mangled, n, &p, &args))
1125 string arg;
1126 string_init (&arg);
1127 string_appendn (declp, *mangled, p - *mangled);
1128 string_append (declp, "<");
1129 /* should do error checking here */
1130 while (args < e) {
1131 string_clear (&arg);
1132 do_type (work, &args, &arg);
1133 string_appends (declp, &arg);
1134 string_append (declp, ",");
1136 string_delete (&arg);
1137 --declp->p;
1138 string_append (declp, ">");
1140 else
1142 string_appendn (declp, *mangled, n);
1144 *mangled += n;
1147 static int
1148 demangle_class_name (work, mangled, declp)
1149 struct work_stuff *work;
1150 const char **mangled;
1151 string *declp;
1153 int n;
1154 int success = 0;
1156 n = consume_count (mangled);
1157 if (strlen (*mangled) >= n)
1159 demangle_arm_pt (work, mangled, n, declp);
1160 success = 1;
1163 return (success);
1168 LOCAL FUNCTION
1170 demangle_class -- demangle a mangled class sequence
1172 SYNOPSIS
1174 static int
1175 demangle_class (struct work_stuff *work, const char **mangled,
1176 strint *declp)
1178 DESCRIPTION
1180 DECLP points to the buffer into which demangling is being done.
1182 *MANGLED points to the current token to be demangled. On input,
1183 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1184 On exit, it points to the next token after the mangled class on
1185 success, or the first unconsumed token on failure.
1187 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1188 we are demangling a constructor or destructor. In this case
1189 we prepend "class::class" or "class::~class" to DECLP.
1191 Otherwise, we prepend "class::" to the current DECLP.
1193 Reset the constructor/destructor flags once they have been
1194 "consumed". This allows demangle_class to be called later during
1195 the same demangling, to do normal class demangling.
1197 Returns 1 if demangling is successful, 0 otherwise.
1201 static int
1202 demangle_class (work, mangled, declp)
1203 struct work_stuff *work;
1204 const char **mangled;
1205 string *declp;
1207 int success = 0;
1208 string class_name;
1210 string_init (&class_name);
1211 if (demangle_class_name (work, mangled, &class_name))
1213 if ((work->constructor & 1) || (work->destructor & 1))
1215 string_prepends (declp, &class_name);
1216 if (work -> destructor & 1)
1218 string_prepend (declp, "~");
1219 work -> destructor -= 1;
1221 else
1223 work -> constructor -= 1;
1226 string_prepend (declp, "::");
1227 string_prepends (declp, &class_name);
1228 success = 1;
1230 string_delete (&class_name);
1231 return (success);
1236 LOCAL FUNCTION
1238 demangle_prefix -- consume the mangled name prefix and find signature
1240 SYNOPSIS
1242 static int
1243 demangle_prefix (struct work_stuff *work, const char **mangled,
1244 string *declp);
1246 DESCRIPTION
1248 Consume and demangle the prefix of the mangled name.
1250 DECLP points to the string buffer into which demangled output is
1251 placed. On entry, the buffer is empty. On exit it contains
1252 the root function name, the demangled operator name, or in some
1253 special cases either nothing or the completely demangled result.
1255 MANGLED points to the current pointer into the mangled name. As each
1256 token of the mangled name is consumed, it is updated. Upon entry
1257 the current mangled name pointer points to the first character of
1258 the mangled name. Upon exit, it should point to the first character
1259 of the signature if demangling was successful, or to the first
1260 unconsumed character if demangling of the prefix was unsuccessful.
1262 Returns 1 on success, 0 otherwise.
1265 static int
1266 demangle_prefix (work, mangled, declp)
1267 struct work_stuff *work;
1268 const char **mangled;
1269 string *declp;
1271 int success = 1;
1272 const char *scan;
1273 int i;
1275 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1277 char *marker = strchr (cplus_markers, (*mangled)[8]);
1278 if (marker != NULL && *marker == (*mangled)[10])
1280 if ((*mangled)[9] == 'D')
1282 /* it's a GNU global destructor to be executed at program exit */
1283 (*mangled) += 11;
1284 work->destructor = 2;
1285 if (gnu_special (work, mangled, declp))
1286 return success;
1288 else if ((*mangled)[9] == 'I')
1290 /* it's a GNU global constructor to be executed at program init */
1291 (*mangled) += 11;
1292 work->constructor = 2;
1293 if (gnu_special (work, mangled, declp))
1294 return success;
1298 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1300 /* it's a ARM global destructor to be executed at program exit */
1301 (*mangled) += 7;
1302 work->destructor = 2;
1304 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1306 /* it's a ARM global constructor to be executed at program initial */
1307 (*mangled) += 7;
1308 work->constructor = 2;
1311 /* This block of code is a reduction in strength time optimization
1313 scan = mystrstr (*mangled, "__"); */
1316 scan = *mangled;
1318 do {
1319 scan = strchr (scan, '_');
1320 } while (scan != NULL && *++scan != '_');
1322 if (scan != NULL) --scan;
1325 if (scan != NULL)
1327 /* We found a sequence of two or more '_', ensure that we start at
1328 the last pair in the sequence. */
1329 i = strspn (scan, "_");
1330 if (i > 2)
1332 scan += (i - 2);
1336 if (scan == NULL)
1338 success = 0;
1340 else if (work -> static_type)
1342 if (!isdigit (scan[0]) && (scan[0] != 't'))
1344 success = 0;
1347 else if ((scan == *mangled) &&
1348 (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
1350 /* The ARM says nothing about the mangling of local variables.
1351 But cfront mangles local variables by prepending __<nesting_level>
1352 to them. As an extension to ARM demangling we handle this case. */
1353 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1355 *mangled = scan + 2;
1356 consume_count (mangled);
1357 string_append (declp, *mangled);
1358 *mangled += strlen (*mangled);
1359 success = 1;
1361 else
1363 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1364 names like __Q2_3foo3bar for nested type names. So don't accept
1365 this style of constructor for cfront demangling. */
1366 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1367 work -> constructor += 1;
1368 *mangled = scan + 2;
1371 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1373 /* Mangled name starts with "__". Skip over any leading '_' characters,
1374 then find the next "__" that separates the prefix from the signature.
1376 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1377 || (arm_special (work, mangled, declp) == 0))
1379 while (*scan == '_')
1381 scan++;
1383 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1385 /* No separator (I.E. "__not_mangled"), or empty signature
1386 (I.E. "__not_mangled_either__") */
1387 success = 0;
1389 else
1391 demangle_function_name (work, mangled, declp, scan);
1395 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1397 /* Cfront-style parameterized type. Handled later as a signature. */
1398 success = 1;
1400 /* ARM template? */
1401 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1403 else if (*(scan + 2) != '\0')
1405 /* Mangled name does not start with "__" but does have one somewhere
1406 in there with non empty stuff after it. Looks like a global
1407 function name. */
1408 demangle_function_name (work, mangled, declp, scan);
1410 else
1412 /* Doesn't look like a mangled name */
1413 success = 0;
1416 if (!success && (work->constructor == 2 || work->destructor == 2))
1418 string_append (declp, *mangled);
1419 *mangled += strlen (*mangled);
1420 success = 1;
1422 return (success);
1427 LOCAL FUNCTION
1429 gnu_special -- special handling of gnu mangled strings
1431 SYNOPSIS
1433 static int
1434 gnu_special (struct work_stuff *work, const char **mangled,
1435 string *declp);
1438 DESCRIPTION
1440 Process some special GNU style mangling forms that don't fit
1441 the normal pattern. For example:
1443 _$_3foo (destructor for class foo)
1444 _vt$foo (foo virtual table)
1445 _vt$foo$bar (foo::bar virtual table)
1446 __vt_foo (foo virtual table, new style with thunks)
1447 _3foo$varname (static data member)
1448 _Q22rs2tu$vw (static data member)
1449 __t6vector1Zii (constructor with template)
1450 __thunk_4__$_7ostream (virtual function thunk)
1453 static int
1454 gnu_special (work, mangled, declp)
1455 struct work_stuff *work;
1456 const char **mangled;
1457 string *declp;
1459 int n;
1460 int success = 1;
1461 const char *p;
1463 if ((*mangled)[0] == '_'
1464 && strchr (cplus_markers, (*mangled)[1]) != NULL
1465 && (*mangled)[2] == '_')
1467 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1468 (*mangled) += 3;
1469 work -> destructor += 1;
1471 else if ((*mangled)[0] == '_'
1472 && (((*mangled)[1] == '_'
1473 && (*mangled)[2] == 'v'
1474 && (*mangled)[3] == 't'
1475 && (*mangled)[4] == '_')
1476 || ((*mangled)[1] == 'v'
1477 && (*mangled)[2] == 't'
1478 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1480 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1481 and create the decl. Note that we consume the entire mangled
1482 input string, which means that demangle_signature has no work
1483 to do. */
1484 if ((*mangled)[2] == 'v')
1485 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1486 else
1487 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1488 while (**mangled != '\0')
1490 p = strpbrk (*mangled, cplus_markers);
1491 switch (**mangled)
1493 case 'Q':
1494 success = demangle_qualified (work, mangled, declp, 0, 1);
1495 break;
1496 case 't':
1497 success = demangle_template (work, mangled, declp, 0);
1498 break;
1499 default:
1500 if (isdigit(*mangled[0]))
1502 n = consume_count(mangled);
1504 else
1506 n = strcspn (*mangled, cplus_markers);
1508 string_appendn (declp, *mangled, n);
1509 (*mangled) += n;
1512 if (success && ((p == NULL) || (p == *mangled)))
1514 if (p != NULL)
1516 string_append (declp, "::");
1517 (*mangled)++;
1520 else
1522 success = 0;
1523 break;
1526 if (success)
1527 string_append (declp, " virtual table");
1529 else if ((*mangled)[0] == '_'
1530 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1531 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1533 /* static data member, "_3foo$varname" for example */
1534 (*mangled)++;
1535 switch (**mangled)
1537 case 'Q':
1538 success = demangle_qualified (work, mangled, declp, 0, 1);
1539 break;
1540 case 't':
1541 success = demangle_template (work, mangled, declp, 0);
1542 break;
1543 default:
1544 n = consume_count (mangled);
1545 string_appendn (declp, *mangled, n);
1546 (*mangled) += n;
1548 if (success && (p == *mangled))
1550 /* Consumed everything up to the cplus_marker, append the
1551 variable name. */
1552 (*mangled)++;
1553 string_append (declp, "::");
1554 n = strlen (*mangled);
1555 string_appendn (declp, *mangled, n);
1556 (*mangled) += n;
1558 else
1560 success = 0;
1563 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1565 int delta = ((*mangled) += 8, consume_count (mangled));
1566 char *method = cplus_demangle (++*mangled, work->options);
1567 if (method)
1569 char buf[50];
1570 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1571 string_append (declp, buf);
1572 string_append (declp, method);
1573 free (method);
1574 n = strlen (*mangled);
1575 (*mangled) += n;
1577 else
1579 success = 0;
1582 else
1584 success = 0;
1586 return (success);
1591 LOCAL FUNCTION
1593 arm_special -- special handling of ARM/lucid mangled strings
1595 SYNOPSIS
1597 static int
1598 arm_special (struct work_stuff *work, const char **mangled,
1599 string *declp);
1602 DESCRIPTION
1604 Process some special ARM style mangling forms that don't fit
1605 the normal pattern. For example:
1607 __vtbl__3foo (foo virtual table)
1608 __vtbl__3foo__3bar (bar::foo virtual table)
1612 static int
1613 arm_special (work, mangled, declp)
1614 struct work_stuff *work;
1615 const char **mangled;
1616 string *declp;
1618 int n;
1619 int success = 1;
1620 const char *scan;
1622 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1624 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1625 and create the decl. Note that we consume the entire mangled
1626 input string, which means that demangle_signature has no work
1627 to do. */
1628 scan = *mangled + ARM_VTABLE_STRLEN;
1629 while (*scan != '\0') /* first check it can be demangled */
1631 n = consume_count (&scan);
1632 if (n==0)
1634 return (0); /* no good */
1636 scan += n;
1637 if (scan[0] == '_' && scan[1] == '_')
1639 scan += 2;
1642 (*mangled) += ARM_VTABLE_STRLEN;
1643 while (**mangled != '\0')
1645 n = consume_count (mangled);
1646 string_prependn (declp, *mangled, n);
1647 (*mangled) += n;
1648 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1650 string_prepend (declp, "::");
1651 (*mangled) += 2;
1654 string_append (declp, " virtual table");
1656 else
1658 success = 0;
1660 return (success);
1665 LOCAL FUNCTION
1667 demangle_qualified -- demangle 'Q' qualified name strings
1669 SYNOPSIS
1671 static int
1672 demangle_qualified (struct work_stuff *, const char *mangled,
1673 string *result, int isfuncname, int append);
1675 DESCRIPTION
1677 Demangle a qualified name, such as "Q25Outer5Inner" which is
1678 the mangled form of "Outer::Inner". The demangled output is
1679 prepended or appended to the result string according to the
1680 state of the append flag.
1682 If isfuncname is nonzero, then the qualified name we are building
1683 is going to be used as a member function name, so if it is a
1684 constructor or destructor function, append an appropriate
1685 constructor or destructor name. I.E. for the above example,
1686 the result for use as a constructor is "Outer::Inner::Inner"
1687 and the result for use as a destructor is "Outer::Inner::~Inner".
1689 BUGS
1691 Numeric conversion is ASCII dependent (FIXME).
1695 static int
1696 demangle_qualified (work, mangled, result, isfuncname, append)
1697 struct work_stuff *work;
1698 const char **mangled;
1699 string *result;
1700 int isfuncname;
1701 int append;
1703 int qualifiers;
1704 int namelength;
1705 int success = 1;
1706 const char *p;
1707 char num[2];
1708 string temp;
1710 string_init (&temp);
1711 switch ((*mangled)[1])
1713 case '_':
1714 /* GNU mangled name with more than 9 classes. The count is preceded
1715 by an underscore (to distinguish it from the <= 9 case) and followed
1716 by an underscore. */
1717 p = *mangled + 2;
1718 qualifiers = atoi (p);
1719 if (!isdigit (*p) || *p == '0')
1720 success = 0;
1722 /* Skip the digits. */
1723 while (isdigit (*p))
1724 ++p;
1726 if (*p != '_')
1727 success = 0;
1729 *mangled = p + 1;
1730 break;
1732 case '1':
1733 case '2':
1734 case '3':
1735 case '4':
1736 case '5':
1737 case '6':
1738 case '7':
1739 case '8':
1740 case '9':
1741 /* The count is in a single digit. */
1742 num[0] = (*mangled)[1];
1743 num[1] = '\0';
1744 qualifiers = atoi (num);
1746 /* If there is an underscore after the digit, skip it. This is
1747 said to be for ARM-qualified names, but the ARM makes no
1748 mention of such an underscore. Perhaps cfront uses one. */
1749 if ((*mangled)[2] == '_')
1751 (*mangled)++;
1753 (*mangled) += 2;
1754 break;
1756 case '0':
1757 default:
1758 success = 0;
1761 if (!success)
1762 return success;
1764 /* Pick off the names and collect them in the temp buffer in the order
1765 in which they are found, separated by '::'. */
1767 while (qualifiers-- > 0)
1769 if (*mangled[0] == '_')
1770 *mangled = *mangled + 1;
1771 if (*mangled[0] == 't')
1773 success = demangle_template(work, mangled, &temp, 0);
1774 if (!success) break;
1776 else
1778 namelength = consume_count (mangled);
1779 if (strlen (*mangled) < namelength)
1781 /* Simple sanity check failed */
1782 success = 0;
1783 break;
1785 string_appendn (&temp, *mangled, namelength);
1786 *mangled += namelength;
1788 if (qualifiers > 0)
1790 string_appendn (&temp, "::", 2);
1794 /* If we are using the result as a function name, we need to append
1795 the appropriate '::' separated constructor or destructor name.
1796 We do this here because this is the most convenient place, where
1797 we already have a pointer to the name and the length of the name. */
1799 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1801 string_appendn (&temp, "::", 2);
1802 if (work -> destructor & 1)
1804 string_append (&temp, "~");
1806 string_appendn (&temp, (*mangled) - namelength, namelength);
1809 /* Now either prepend the temp buffer to the result, or append it,
1810 depending upon the state of the append flag. */
1812 if (append)
1814 string_appends (result, &temp);
1816 else
1818 if (!STRING_EMPTY (result))
1820 string_appendn (&temp, "::", 2);
1822 string_prepends (result, &temp);
1825 string_delete (&temp);
1826 return (success);
1831 LOCAL FUNCTION
1833 get_count -- convert an ascii count to integer, consuming tokens
1835 SYNOPSIS
1837 static int
1838 get_count (const char **type, int *count)
1840 DESCRIPTION
1842 Return 0 if no conversion is performed, 1 if a string is converted.
1845 static int
1846 get_count (type, count)
1847 const char **type;
1848 int *count;
1850 const char *p;
1851 int n;
1853 if (!isdigit (**type))
1855 return (0);
1857 else
1859 *count = **type - '0';
1860 (*type)++;
1861 if (isdigit (**type))
1863 p = *type;
1864 n = *count;
1867 n *= 10;
1868 n += *p - '0';
1869 p++;
1871 while (isdigit (*p));
1872 if (*p == '_')
1874 *type = p + 1;
1875 *count = n;
1879 return (1);
1882 /* result will be initialised here; it will be freed on failure */
1884 static int
1885 do_type (work, mangled, result)
1886 struct work_stuff *work;
1887 const char **mangled;
1888 string *result;
1890 int n;
1891 int done;
1892 int success;
1893 string decl;
1894 const char *remembered_type;
1895 int constp;
1896 int volatilep;
1898 string_init (&decl);
1899 string_init (result);
1901 done = 0;
1902 success = 1;
1903 while (success && !done)
1905 int member;
1906 switch (**mangled)
1909 /* A pointer type */
1910 case 'P':
1911 case 'p':
1912 (*mangled)++;
1913 string_prepend (&decl, "*");
1914 break;
1916 /* A reference type */
1917 case 'R':
1918 (*mangled)++;
1919 string_prepend (&decl, "&");
1920 break;
1922 /* An array */
1923 case 'A':
1925 const char *p = ++(*mangled);
1927 string_prepend (&decl, "(");
1928 string_append (&decl, ")[");
1929 /* Copy anything up until the next underscore (the size of the
1930 array). */
1931 while (**mangled && **mangled != '_')
1932 ++(*mangled);
1933 if (**mangled == '_')
1935 string_appendn (&decl, p, *mangled - p);
1936 string_append (&decl, "]");
1937 *mangled += 1;
1939 else
1940 success = 0;
1941 break;
1944 /* A back reference to a previously seen type */
1945 case 'T':
1946 (*mangled)++;
1947 if (!get_count (mangled, &n) || n >= work -> ntypes)
1949 success = 0;
1951 else
1953 remembered_type = work -> typevec[n];
1954 mangled = &remembered_type;
1956 break;
1958 /* A function */
1959 case 'F':
1960 (*mangled)++;
1961 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
1963 string_prepend (&decl, "(");
1964 string_append (&decl, ")");
1966 /* After picking off the function args, we expect to either find the
1967 function return type (preceded by an '_') or the end of the
1968 string. */
1969 if (!demangle_args (work, mangled, &decl)
1970 || (**mangled != '_' && **mangled != '\0'))
1972 success = 0;
1974 if (success && (**mangled == '_'))
1976 (*mangled)++;
1978 break;
1980 case 'M':
1981 case 'O':
1983 constp = 0;
1984 volatilep = 0;
1986 member = **mangled == 'M';
1987 (*mangled)++;
1988 if (!isdigit (**mangled))
1990 success = 0;
1991 break;
1993 n = consume_count (mangled);
1994 if (strlen (*mangled) < n)
1996 success = 0;
1997 break;
1999 string_append (&decl, ")");
2000 string_prepend (&decl, "::");
2001 string_prependn (&decl, *mangled, n);
2002 string_prepend (&decl, "(");
2003 *mangled += n;
2004 if (member)
2006 if (**mangled == 'C')
2008 (*mangled)++;
2009 constp = 1;
2011 if (**mangled == 'V')
2013 (*mangled)++;
2014 volatilep = 1;
2016 if (*(*mangled)++ != 'F')
2018 success = 0;
2019 break;
2022 if ((member && !demangle_args (work, mangled, &decl))
2023 || **mangled != '_')
2025 success = 0;
2026 break;
2028 (*mangled)++;
2029 if (! PRINT_ANSI_QUALIFIERS)
2031 break;
2033 if (constp)
2035 APPEND_BLANK (&decl);
2036 string_append (&decl, "const");
2038 if (volatilep)
2040 APPEND_BLANK (&decl);
2041 string_append (&decl, "volatile");
2043 break;
2045 case 'G':
2046 (*mangled)++;
2047 break;
2049 case 'C':
2050 (*mangled)++;
2052 if ((*mangled)[1] == 'P')
2055 if (PRINT_ANSI_QUALIFIERS)
2057 if (!STRING_EMPTY (&decl))
2059 string_prepend (&decl, " ");
2061 string_prepend (&decl, "const");
2063 break;
2068 /* fall through */
2069 default:
2070 done = 1;
2071 break;
2075 switch (**mangled)
2077 /* A qualified name, such as "Outer::Inner". */
2078 case 'Q':
2079 success = demangle_qualified (work, mangled, result, 0, 1);
2080 break;
2082 default:
2083 success = demangle_fund_type (work, mangled, result);
2084 break;
2087 if (success)
2089 if (!STRING_EMPTY (&decl))
2091 string_append (result, " ");
2092 string_appends (result, &decl);
2095 else
2097 string_delete (result);
2099 string_delete (&decl);
2100 return (success);
2103 /* Given a pointer to a type string that represents a fundamental type
2104 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2105 string in which the demangled output is being built in RESULT, and
2106 the WORK structure, decode the types and add them to the result.
2108 For example:
2110 "Ci" => "const int"
2111 "Sl" => "signed long"
2112 "CUs" => "const unsigned short"
2116 static int
2117 demangle_fund_type (work, mangled, result)
2118 struct work_stuff *work;
2119 const char **mangled;
2120 string *result;
2122 int done = 0;
2123 int success = 1;
2125 /* First pick off any type qualifiers. There can be more than one. */
2127 while (!done)
2129 switch (**mangled)
2131 case 'C':
2132 (*mangled)++;
2133 if (PRINT_ANSI_QUALIFIERS)
2135 APPEND_BLANK (result);
2136 string_append (result, "const");
2138 break;
2139 case 'U':
2140 (*mangled)++;
2141 APPEND_BLANK (result);
2142 string_append (result, "unsigned");
2143 break;
2144 case 'S': /* signed char only */
2145 (*mangled)++;
2146 APPEND_BLANK (result);
2147 string_append (result, "signed");
2148 break;
2149 case 'V':
2150 (*mangled)++;
2151 if (PRINT_ANSI_QUALIFIERS)
2153 APPEND_BLANK (result);
2154 string_append (result, "volatile");
2156 break;
2157 default:
2158 done = 1;
2159 break;
2163 /* Now pick off the fundamental type. There can be only one. */
2165 switch (**mangled)
2167 case '\0':
2168 case '_':
2169 break;
2170 case 'v':
2171 (*mangled)++;
2172 APPEND_BLANK (result);
2173 string_append (result, "void");
2174 break;
2175 case 'x':
2176 (*mangled)++;
2177 APPEND_BLANK (result);
2178 string_append (result, "long long");
2179 break;
2180 case 'l':
2181 (*mangled)++;
2182 APPEND_BLANK (result);
2183 string_append (result, "long");
2184 break;
2185 case 'i':
2186 (*mangled)++;
2187 APPEND_BLANK (result);
2188 string_append (result, "int");
2189 break;
2190 case 's':
2191 (*mangled)++;
2192 APPEND_BLANK (result);
2193 string_append (result, "short");
2194 break;
2195 case 'b':
2196 (*mangled)++;
2197 APPEND_BLANK (result);
2198 string_append (result, "bool");
2199 break;
2200 case 'c':
2201 (*mangled)++;
2202 APPEND_BLANK (result);
2203 string_append (result, "char");
2204 break;
2205 case 'w':
2206 (*mangled)++;
2207 APPEND_BLANK (result);
2208 string_append (result, "wchar_t");
2209 break;
2210 case 'r':
2211 (*mangled)++;
2212 APPEND_BLANK (result);
2213 string_append (result, "long double");
2214 break;
2215 case 'd':
2216 (*mangled)++;
2217 APPEND_BLANK (result);
2218 string_append (result, "double");
2219 break;
2220 case 'f':
2221 (*mangled)++;
2222 APPEND_BLANK (result);
2223 string_append (result, "float");
2224 break;
2225 case 'G':
2226 (*mangled)++;
2227 if (!isdigit (**mangled))
2229 success = 0;
2230 break;
2232 /* fall through */
2233 /* An explicit type, such as "6mytype" or "7integer" */
2234 case '0':
2235 case '1':
2236 case '2':
2237 case '3':
2238 case '4':
2239 case '5':
2240 case '6':
2241 case '7':
2242 case '8':
2243 case '9':
2244 APPEND_BLANK (result);
2245 if (!demangle_class_name (work, mangled, result)) {
2246 --result->p;
2247 success = 0;
2249 break;
2250 case 't':
2251 success = demangle_template(work,mangled, result, 0);
2252 break;
2253 default:
2254 success = 0;
2255 break;
2258 return (success);
2261 /* `result' will be initialized in do_type; it will be freed on failure */
2263 static int
2264 do_arg (work, mangled, result)
2265 struct work_stuff *work;
2266 const char **mangled;
2267 string *result;
2269 const char *start = *mangled;
2271 if (!do_type (work, mangled, result))
2273 return (0);
2275 else
2277 remember_type (work, start, *mangled - start);
2278 return (1);
2282 static void
2283 remember_type (work, start, len)
2284 struct work_stuff *work;
2285 const char *start;
2286 int len;
2288 char *tem;
2290 if (work -> ntypes >= work -> typevec_size)
2292 if (work -> typevec_size == 0)
2294 work -> typevec_size = 3;
2295 work -> typevec =
2296 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2298 else
2300 work -> typevec_size *= 2;
2301 work -> typevec =
2302 (char **) xrealloc ((char *)work -> typevec,
2303 sizeof (char *) * work -> typevec_size);
2306 tem = xmalloc (len + 1);
2307 memcpy (tem, start, len);
2308 tem[len] = '\0';
2309 work -> typevec[work -> ntypes++] = tem;
2312 /* Forget the remembered types, but not the type vector itself. */
2314 static void
2315 forget_types (work)
2316 struct work_stuff *work;
2318 int i;
2320 while (work -> ntypes > 0)
2322 i = --(work -> ntypes);
2323 if (work -> typevec[i] != NULL)
2325 free (work -> typevec[i]);
2326 work -> typevec[i] = NULL;
2331 /* Process the argument list part of the signature, after any class spec
2332 has been consumed, as well as the first 'F' character (if any). For
2333 example:
2335 "__als__3fooRT0" => process "RT0"
2336 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2338 DECLP must be already initialised, usually non-empty. It won't be freed
2339 on failure.
2341 Note that g++ differs significantly from ARM and lucid style mangling
2342 with regards to references to previously seen types. For example, given
2343 the source fragment:
2345 class foo {
2346 public:
2347 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2350 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2351 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2353 g++ produces the names:
2355 __3fooiRT0iT2iT2
2356 foo__FiR3fooiT1iT1
2358 while lcc (and presumably other ARM style compilers as well) produces:
2360 foo__FiR3fooT1T2T1T2
2361 __ct__3fooFiR3fooT1T2T1T2
2363 Note that g++ bases it's type numbers starting at zero and counts all
2364 previously seen types, while lucid/ARM bases it's type numbers starting
2365 at one and only considers types after it has seen the 'F' character
2366 indicating the start of the function args. For lucid/ARM style, we
2367 account for this difference by discarding any previously seen types when
2368 we see the 'F' character, and subtracting one from the type number
2369 reference.
2373 static int
2374 demangle_args (work, mangled, declp)
2375 struct work_stuff *work;
2376 const char **mangled;
2377 string *declp;
2379 string arg;
2380 int need_comma = 0;
2381 int r;
2382 int t;
2383 const char *tem;
2384 char temptype;
2386 if (PRINT_ARG_TYPES)
2388 string_append (declp, "(");
2389 if (**mangled == '\0')
2391 string_append (declp, "void");
2395 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2397 if ((**mangled == 'N') || (**mangled == 'T'))
2399 temptype = *(*mangled)++;
2401 if (temptype == 'N')
2403 if (!get_count (mangled, &r))
2405 return (0);
2408 else
2410 r = 1;
2412 if (ARM_DEMANGLING && work -> ntypes >= 10)
2414 /* If we have 10 or more types we might have more than a 1 digit
2415 index so we'll have to consume the whole count here. This
2416 will lose if the next thing is a type name preceded by a
2417 count but it's impossible to demangle that case properly
2418 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2419 Pc, ...)" or "(..., type12, char *, ...)" */
2420 if ((t = consume_count(mangled)) == 0)
2422 return (0);
2425 else
2427 if (!get_count (mangled, &t))
2429 return (0);
2432 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2434 t--;
2436 /* Validate the type index. Protect against illegal indices from
2437 malformed type strings. */
2438 if ((t < 0) || (t >= work -> ntypes))
2440 return (0);
2442 while (--r >= 0)
2444 tem = work -> typevec[t];
2445 if (need_comma && PRINT_ARG_TYPES)
2447 string_append (declp, ", ");
2449 if (!do_arg (work, &tem, &arg))
2451 return (0);
2453 if (PRINT_ARG_TYPES)
2455 string_appends (declp, &arg);
2457 string_delete (&arg);
2458 need_comma = 1;
2461 else
2463 if (need_comma & PRINT_ARG_TYPES)
2465 string_append (declp, ", ");
2467 if (!do_arg (work, mangled, &arg))
2469 return (0);
2471 if (PRINT_ARG_TYPES)
2473 string_appends (declp, &arg);
2475 string_delete (&arg);
2476 need_comma = 1;
2480 if (**mangled == 'e')
2482 (*mangled)++;
2483 if (PRINT_ARG_TYPES)
2485 if (need_comma)
2487 string_append (declp, ",");
2489 string_append (declp, "...");
2493 if (PRINT_ARG_TYPES)
2495 string_append (declp, ")");
2497 return (1);
2500 static void
2501 demangle_function_name (work, mangled, declp, scan)
2502 struct work_stuff *work;
2503 const char **mangled;
2504 string *declp;
2505 const char *scan;
2507 int i;
2508 int len;
2509 string type;
2510 const char *tem;
2512 string_appendn (declp, (*mangled), scan - (*mangled));
2513 string_need (declp, 1);
2514 *(declp -> p) = '\0';
2516 /* Consume the function name, including the "__" separating the name
2517 from the signature. We are guaranteed that SCAN points to the
2518 separator. */
2520 (*mangled) = scan + 2;
2522 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2525 /* See if we have an ARM style constructor or destructor operator.
2526 If so, then just record it, clear the decl, and return.
2527 We can't build the actual constructor/destructor decl until later,
2528 when we recover the class name from the signature. */
2530 if (strcmp (declp -> b, "__ct") == 0)
2532 work -> constructor += 1;
2533 string_clear (declp);
2534 return;
2536 else if (strcmp (declp -> b, "__dt") == 0)
2538 work -> destructor += 1;
2539 string_clear (declp);
2540 return;
2544 if (declp->p - declp->b >= 3
2545 && declp->b[0] == 'o'
2546 && declp->b[1] == 'p'
2547 && strchr (cplus_markers, declp->b[2]) != NULL)
2549 /* see if it's an assignment expression */
2550 if (declp->p - declp->b >= 10 /* op$assign_ */
2551 && memcmp (declp->b + 3, "assign_", 7) == 0)
2553 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2555 len = declp->p - declp->b - 10;
2556 if (strlen (optable[i].in) == len
2557 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2559 string_clear (declp);
2560 string_append (declp, "operator");
2561 string_append (declp, optable[i].out);
2562 string_append (declp, "=");
2563 break;
2567 else
2569 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2571 int len = declp->p - declp->b - 3;
2572 if (strlen (optable[i].in) == len
2573 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2575 string_clear (declp);
2576 string_append (declp, "operator");
2577 string_append (declp, optable[i].out);
2578 break;
2583 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2584 && strchr (cplus_markers, declp->b[4]) != NULL)
2586 /* type conversion operator */
2587 tem = declp->b + 5;
2588 if (do_type (work, &tem, &type))
2590 string_clear (declp);
2591 string_append (declp, "operator ");
2592 string_appends (declp, &type);
2593 string_delete (&type);
2596 else if (declp->b[0] == '_' && declp->b[1] == '_'
2597 && declp->b[2] == 'o' && declp->b[3] == 'p')
2599 /* ANSI. */
2600 /* type conversion operator. */
2601 tem = declp->b + 4;
2602 if (do_type (work, &tem, &type))
2604 string_clear (declp);
2605 string_append (declp, "operator ");
2606 string_appends (declp, &type);
2607 string_delete (&type);
2610 else if (declp->b[0] == '_' && declp->b[1] == '_'
2611 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2612 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2614 if (declp->b[4] == '\0')
2616 /* Operator. */
2617 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2619 if (strlen (optable[i].in) == 2
2620 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2622 string_clear (declp);
2623 string_append (declp, "operator");
2624 string_append (declp, optable[i].out);
2625 break;
2629 else
2631 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2633 /* Assignment. */
2634 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2636 if (strlen (optable[i].in) == 3
2637 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2639 string_clear (declp);
2640 string_append (declp, "operator");
2641 string_append (declp, optable[i].out);
2642 break;
2650 /* a mini string-handling package */
2652 static void
2653 string_need (s, n)
2654 string *s;
2655 int n;
2657 int tem;
2659 if (s->b == NULL)
2661 if (n < 32)
2663 n = 32;
2665 s->p = s->b = xmalloc (n);
2666 s->e = s->b + n;
2668 else if (s->e - s->p < n)
2670 tem = s->p - s->b;
2671 n += tem;
2672 n *= 2;
2673 s->b = xrealloc (s->b, n);
2674 s->p = s->b + tem;
2675 s->e = s->b + n;
2679 static void
2680 string_delete (s)
2681 string *s;
2683 if (s->b != NULL)
2685 free (s->b);
2686 s->b = s->e = s->p = NULL;
2690 static void
2691 string_init (s)
2692 string *s;
2694 s->b = s->p = s->e = NULL;
2697 static void
2698 string_clear (s)
2699 string *s;
2701 s->p = s->b;
2704 #if 0
2706 static int
2707 string_empty (s)
2708 string *s;
2710 return (s->b == s->p);
2713 #endif
2715 static void
2716 string_append (p, s)
2717 string *p;
2718 const char *s;
2720 int n;
2721 if (s == NULL || *s == '\0')
2722 return;
2723 n = strlen (s);
2724 string_need (p, n);
2725 memcpy (p->p, s, n);
2726 p->p += n;
2729 static void
2730 string_appends (p, s)
2731 string *p, *s;
2733 int n;
2735 if (s->b != s->p)
2737 n = s->p - s->b;
2738 string_need (p, n);
2739 memcpy (p->p, s->b, n);
2740 p->p += n;
2744 static void
2745 string_appendn (p, s, n)
2746 string *p;
2747 const char *s;
2748 int n;
2750 if (n != 0)
2752 string_need (p, n);
2753 memcpy (p->p, s, n);
2754 p->p += n;
2758 static void
2759 string_prepend (p, s)
2760 string *p;
2761 const char *s;
2763 if (s != NULL && *s != '\0')
2765 string_prependn (p, s, strlen (s));
2769 static void
2770 string_prepends (p, s)
2771 string *p, *s;
2773 if (s->b != s->p)
2775 string_prependn (p, s->b, s->p - s->b);
2779 static void
2780 string_prependn (p, s, n)
2781 string *p;
2782 const char *s;
2783 int n;
2785 char *q;
2787 if (n != 0)
2789 string_need (p, n);
2790 for (q = p->p - 1; q >= p->b; q--)
2792 q[n] = q[0];
2794 memcpy (p->b, s, n);
2795 p->p += n;
2799 /* To generate a standalone demangler program for testing purposes,
2800 just compile and link this file with -DMAIN and libiberty.a. When
2801 run, it demangles each command line arg, or each stdin string, and
2802 prints the result on stdout. */
2804 #ifdef MAIN
2806 static void
2807 demangle_it (mangled_name)
2808 char *mangled_name;
2810 char *result;
2812 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2813 if (result == NULL)
2815 printf ("%s\n", mangled_name);
2817 else
2819 printf ("%s\n", result);
2820 free (result);
2824 #include "getopt.h"
2826 static char *program_name;
2827 static char *program_version = VERSION;
2829 static void
2830 usage (stream, status)
2831 FILE *stream;
2832 int status;
2834 fprintf (stream, "\
2835 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2836 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2837 [--help] [--version] [arg...]\n",
2838 program_name);
2839 exit (status);
2842 #define MBUF_SIZE 512
2843 char mbuffer[MBUF_SIZE];
2845 /* Defined in the automatically-generated underscore.c. */
2846 extern int prepends_underscore;
2848 int strip_underscore = 0;
2850 static struct option long_options[] = {
2851 {"strip-underscores", no_argument, 0, '_'},
2852 {"format", required_argument, 0, 's'},
2853 {"help", no_argument, 0, 'h'},
2854 {"no-strip-underscores", no_argument, 0, 'n'},
2855 {"version", no_argument, 0, 'v'},
2856 {0, no_argument, 0, 0}
2860 main (argc, argv)
2861 int argc;
2862 char **argv;
2864 char *result;
2865 int c;
2867 program_name = argv[0];
2869 strip_underscore = prepends_underscore;
2871 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2873 switch (c)
2875 case '?':
2876 usage (stderr, 1);
2877 break;
2878 case 'h':
2879 usage (stdout, 0);
2880 case 'n':
2881 strip_underscore = 0;
2882 break;
2883 case 'v':
2884 printf ("GNU %s version %s\n", program_name, program_version);
2885 exit (0);
2886 case '_':
2887 strip_underscore = 1;
2888 break;
2889 case 's':
2890 if (strcmp (optarg, "gnu") == 0)
2892 current_demangling_style = gnu_demangling;
2894 else if (strcmp (optarg, "lucid") == 0)
2896 current_demangling_style = lucid_demangling;
2898 else if (strcmp (optarg, "arm") == 0)
2900 current_demangling_style = arm_demangling;
2902 else
2904 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2905 program_name, optarg);
2906 exit (1);
2908 break;
2912 if (optind < argc)
2914 for ( ; optind < argc; optind++)
2916 demangle_it (argv[optind]);
2919 else
2921 for (;;)
2923 int i = 0;
2924 c = getchar ();
2925 /* Try to read a label. */
2926 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2928 if (i >= MBUF_SIZE-1)
2929 break;
2930 mbuffer[i++] = c;
2931 c = getchar ();
2933 if (i > 0)
2935 int skip_first = 0;
2937 if (mbuffer[0] == '.')
2938 ++skip_first;
2939 if (strip_underscore && mbuffer[skip_first] == '_')
2940 ++skip_first;
2942 if (skip_first > i)
2943 skip_first = i;
2945 mbuffer[i] = 0;
2947 result = cplus_demangle (mbuffer + skip_first,
2948 DMGL_PARAMS | DMGL_ANSI);
2949 if (result)
2951 if (mbuffer[0] == '.')
2952 putc ('.', stdout);
2953 fputs (result, stdout);
2954 free (result);
2956 else
2957 fputs (mbuffer, stdout);
2959 fflush (stdout);
2961 if (c == EOF)
2962 break;
2963 putchar (c);
2967 exit (0);
2970 static void
2971 fatal (str)
2972 char *str;
2974 fprintf (stderr, "%s: %s\n", program_name, str);
2975 exit (1);
2978 char * malloc ();
2979 char * realloc ();
2981 char *
2982 xmalloc (size)
2983 unsigned size;
2985 register char *value = (char *) malloc (size);
2986 if (value == 0)
2987 fatal ("virtual memory exhausted");
2988 return value;
2991 char *
2992 xrealloc (ptr, size)
2993 char *ptr;
2994 unsigned size;
2996 register char *value = (char *) realloc (ptr, size);
2997 if (value == 0)
2998 fatal ("virtual memory exhausted");
2999 return value;
3001 #endif /* main */