Add configuration for semi-hosted ARM.
[official-gcc.git] / gcc / cplus-dem.c
blobb56e34e251780707a5470130be9304a654e12115
1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995 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., 675 Mass Ave,
20 Cambridge, MA 02139, 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));
38 extern char *strstr ();
40 /* In order to allow a single demangler executable to demangle strings
41 using various common values of CPLUS_MARKER, as well as any specific
42 one set at compile time, we maintain a string containing all the
43 commonly used ones, and check to see if the marker we are looking for
44 is in that string. CPLUS_MARKER is usually '$' on systems where the
45 assembler can deal with that. Where the assembler can't, it's usually
46 '.' (but on many systems '.' is used for other things). We put the
47 current defined CPLUS_MARKER first (which defaults to '$'), followed
48 by the next most common value, followed by an explicit '$' in case
49 the value of CPLUS_MARKER is not '$'.
51 We could avoid this if we could just get g++ to tell us what the actual
52 cplus marker character is as part of the debug information, perhaps by
53 ensuring that it is the character that terminates the gcc<n>_compiled
54 marker symbol (FIXME). */
56 #if !defined (CPLUS_MARKER)
57 #define CPLUS_MARKER '$'
58 #endif
60 enum demangling_styles current_demangling_style = gnu_demangling;
62 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
64 void
65 set_cplus_marker_for_demangling (ch)
66 int ch;
68 cplus_markers[0] = ch;
71 /* Stuff that is shared between sub-routines.
72 * Using a shared structure allows cplus_demangle to be reentrant. */
74 struct work_stuff
76 int options;
77 char **typevec;
78 int ntypes;
79 int typevec_size;
80 int constructor;
81 int destructor;
82 int static_type; /* A static member function */
83 int const_type; /* A const member function */
86 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
87 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
89 static const struct optable
91 const char *in;
92 const char *out;
93 int flags;
94 } optable[] = {
95 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
96 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
97 {"new", " new", 0}, /* old (1.91, and 1.x) */
98 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
99 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
100 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
101 {"as", "=", DMGL_ANSI}, /* ansi */
102 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
103 {"eq", "==", DMGL_ANSI}, /* old, ansi */
104 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
105 {"gt", ">", DMGL_ANSI}, /* old, ansi */
106 {"le", "<=", DMGL_ANSI}, /* old, ansi */
107 {"lt", "<", DMGL_ANSI}, /* old, ansi */
108 {"plus", "+", 0}, /* old */
109 {"pl", "+", DMGL_ANSI}, /* ansi */
110 {"apl", "+=", DMGL_ANSI}, /* ansi */
111 {"minus", "-", 0}, /* old */
112 {"mi", "-", DMGL_ANSI}, /* ansi */
113 {"ami", "-=", DMGL_ANSI}, /* ansi */
114 {"mult", "*", 0}, /* old */
115 {"ml", "*", DMGL_ANSI}, /* ansi */
116 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
117 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
118 {"convert", "+", 0}, /* old (unary +) */
119 {"negate", "-", 0}, /* old (unary -) */
120 {"trunc_mod", "%", 0}, /* old */
121 {"md", "%", DMGL_ANSI}, /* ansi */
122 {"amd", "%=", DMGL_ANSI}, /* ansi */
123 {"trunc_div", "/", 0}, /* old */
124 {"dv", "/", DMGL_ANSI}, /* ansi */
125 {"adv", "/=", DMGL_ANSI}, /* ansi */
126 {"truth_andif", "&&", 0}, /* old */
127 {"aa", "&&", DMGL_ANSI}, /* ansi */
128 {"truth_orif", "||", 0}, /* old */
129 {"oo", "||", DMGL_ANSI}, /* ansi */
130 {"truth_not", "!", 0}, /* old */
131 {"nt", "!", DMGL_ANSI}, /* ansi */
132 {"postincrement","++", 0}, /* old */
133 {"pp", "++", DMGL_ANSI}, /* ansi */
134 {"postdecrement","--", 0}, /* old */
135 {"mm", "--", DMGL_ANSI}, /* ansi */
136 {"bit_ior", "|", 0}, /* old */
137 {"or", "|", DMGL_ANSI}, /* ansi */
138 {"aor", "|=", DMGL_ANSI}, /* ansi */
139 {"bit_xor", "^", 0}, /* old */
140 {"er", "^", DMGL_ANSI}, /* ansi */
141 {"aer", "^=", DMGL_ANSI}, /* ansi */
142 {"bit_and", "&", 0}, /* old */
143 {"ad", "&", DMGL_ANSI}, /* ansi */
144 {"aad", "&=", DMGL_ANSI}, /* ansi */
145 {"bit_not", "~", 0}, /* old */
146 {"co", "~", DMGL_ANSI}, /* ansi */
147 {"call", "()", 0}, /* old */
148 {"cl", "()", DMGL_ANSI}, /* ansi */
149 {"alshift", "<<", 0}, /* old */
150 {"ls", "<<", DMGL_ANSI}, /* ansi */
151 {"als", "<<=", DMGL_ANSI}, /* ansi */
152 {"arshift", ">>", 0}, /* old */
153 {"rs", ">>", DMGL_ANSI}, /* ansi */
154 {"ars", ">>=", DMGL_ANSI}, /* ansi */
155 {"component", "->", 0}, /* old */
156 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
157 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
158 {"indirect", "*", 0}, /* old */
159 {"method_call", "->()", 0}, /* old */
160 {"addr", "&", 0}, /* old (unary &) */
161 {"array", "[]", 0}, /* old */
162 {"vc", "[]", DMGL_ANSI}, /* ansi */
163 {"compound", ", ", 0}, /* old */
164 {"cm", ", ", DMGL_ANSI}, /* ansi */
165 {"cond", "?:", 0}, /* old */
166 {"cn", "?:", DMGL_ANSI}, /* psuedo-ansi */
167 {"max", ">?", 0}, /* old */
168 {"mx", ">?", DMGL_ANSI}, /* psuedo-ansi */
169 {"min", "<?", 0}, /* old */
170 {"mn", "<?", DMGL_ANSI}, /* psuedo-ansi */
171 {"nop", "", 0}, /* old (for operator=) */
172 {"rm", "->*", DMGL_ANSI} /* ansi */
176 typedef struct string /* Beware: these aren't required to be */
177 { /* '\0' terminated. */
178 char *b; /* pointer to start of string */
179 char *p; /* pointer after last character */
180 char *e; /* pointer after end of allocated space */
181 } string;
183 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
184 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
185 string_prepend(str, " ");}
186 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
187 string_append(str, " ");}
189 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
190 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
192 /* Prototypes for local functions */
194 static char *
195 mop_up PARAMS ((struct work_stuff *, string *, int));
197 #if 0
198 static int
199 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
200 #endif
202 static int
203 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
204 string *));
206 static int
207 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
208 int, int));
210 static int
211 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
213 static int
214 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
216 static int
217 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
219 static int
220 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
222 static int
223 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
225 static int
226 arm_special PARAMS ((struct work_stuff *, const char **, string *));
228 static void
229 string_need PARAMS ((string *, int));
231 static void
232 string_delete PARAMS ((string *));
234 static void
235 string_init PARAMS ((string *));
237 static void
238 string_clear PARAMS ((string *));
240 #if 0
241 static int
242 string_empty PARAMS ((string *));
243 #endif
245 static void
246 string_append PARAMS ((string *, const char *));
248 static void
249 string_appends PARAMS ((string *, string *));
251 static void
252 string_appendn PARAMS ((string *, const char *, int));
254 static void
255 string_prepend PARAMS ((string *, const char *));
257 static void
258 string_prependn PARAMS ((string *, const char *, int));
260 static int
261 get_count PARAMS ((const char **, int *));
263 static int
264 consume_count PARAMS ((const char **));
266 static int
267 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
269 static int
270 do_type PARAMS ((struct work_stuff *, const char **, string *));
272 static int
273 do_arg PARAMS ((struct work_stuff *, const char **, string *));
275 static void
276 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
277 const char *));
279 static void
280 remember_type PARAMS ((struct work_stuff *, const char *, int));
282 static void
283 forget_types PARAMS ((struct work_stuff *));
285 static void
286 string_prepends PARAMS ((string *, string *));
288 /* Translate count to integer, consuming tokens in the process.
289 Conversion terminates on the first non-digit character.
290 Trying to consume something that isn't a count results in
291 no consumption of input and a return of 0. */
293 static int
294 consume_count (type)
295 const char **type;
297 int count = 0;
299 while (isdigit (**type))
301 count *= 10;
302 count += **type - '0';
303 (*type)++;
305 return (count);
309 cplus_demangle_opname (opname, result, options)
310 char *opname;
311 char *result;
312 int options;
314 int len, i, len1, ret;
315 string type;
316 struct work_stuff work[1];
317 const char *tem;
319 len = strlen(opname);
320 result[0] = '\0';
321 ret = 0;
322 work->options = options;
324 if (opname[0] == '_' && opname[1] == '_'
325 && opname[2] == 'o' && opname[3] == 'p')
327 /* ANSI. */
328 /* type conversion operator. */
329 tem = opname + 4;
330 if (do_type (work, &tem, &type))
332 strcat (result, "operator ");
333 strncat (result, type.b, type.p - type.b);
334 string_delete (&type);
335 ret = 1;
338 else if (opname[0] == '_' && opname[1] == '_'
339 && opname[2] >= 'a' && opname[2] <= 'z'
340 && opname[3] >= 'a' && opname[3] <= 'z')
342 if (opname[4] == '\0')
344 /* Operator. */
345 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
347 if (strlen (optable[i].in) == 2
348 && memcmp (optable[i].in, opname + 2, 2) == 0)
350 strcat (result, "operator");
351 strcat (result, optable[i].out);
352 ret = 1;
353 break;
357 else
359 if (opname[2] == 'a' && opname[5] == '\0')
361 /* Assignment. */
362 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
364 if (strlen (optable[i].in) == 3
365 && memcmp (optable[i].in, opname + 2, 3) == 0)
367 strcat (result, "operator");
368 strcat (result, optable[i].out);
369 ret = 1;
370 break;
376 else if (len >= 3
377 && opname[0] == 'o'
378 && opname[1] == 'p'
379 && strchr (cplus_markers, opname[2]) != NULL)
381 /* see if it's an assignment expression */
382 if (len >= 10 /* op$assign_ */
383 && memcmp (opname + 3, "assign_", 7) == 0)
385 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
387 len1 = len - 10;
388 if (strlen (optable[i].in) == len1
389 && memcmp (optable[i].in, opname + 10, len1) == 0)
391 strcat (result, "operator");
392 strcat (result, optable[i].out);
393 strcat (result, "=");
394 ret = 1;
395 break;
399 else
401 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
403 len1 = len - 3;
404 if (strlen (optable[i].in) == len1
405 && memcmp (optable[i].in, opname + 3, len1) == 0)
407 strcat (result, "operator");
408 strcat (result, optable[i].out);
409 ret = 1;
410 break;
415 else if (len >= 5 && memcmp (opname, "type", 4) == 0
416 && strchr (cplus_markers, opname[4]) != NULL)
418 /* type conversion operator */
419 tem = opname + 5;
420 if (do_type (work, &tem, &type))
422 strcat (result, "operator ");
423 strncat (result, type.b, type.p - type.b);
424 string_delete (&type);
425 ret = 1;
428 return ret;
431 /* Takes operator name as e.g. "++" and returns mangled
432 operator name (e.g. "postincrement_expr"), or NULL if not found.
434 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
435 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
437 char *
438 cplus_mangle_opname (opname, options)
439 char *opname;
440 int options;
442 int i;
443 int len;
445 len = strlen (opname);
446 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
448 if (strlen (optable[i].out) == len
449 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
450 && memcmp (optable[i].out, opname, len) == 0)
451 return ((char *)optable[i].in);
453 return (0);
456 /* check to see whether MANGLED can match TEXT in the first TEXT_LEN
457 characters. */
459 int cplus_match (mangled, text, text_len)
460 const char *mangled;
461 char *text;
462 int text_len;
464 if (strncmp (mangled, text, text_len) != 0) {
465 return(0); /* cannot match either */
466 } else {
467 return(1); /* matches mangled, may match demangled */
471 /* char *cplus_demangle (const char *mangled, int options)
473 If MANGLED is a mangled function name produced by GNU C++, then
474 a pointer to a malloced string giving a C++ representation
475 of the name will be returned; otherwise NULL will be returned.
476 It is the caller's responsibility to free the string which
477 is returned.
479 The OPTIONS arg may contain one or more of the following bits:
481 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
482 included.
483 DMGL_PARAMS Function parameters are included.
485 For example,
487 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
488 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
489 cplus_demangle ("foo__1Ai", 0) => "A::foo"
491 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
492 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
493 cplus_demangle ("foo__1Afe", 0) => "A::foo"
495 Note that any leading underscores, or other such characters prepended by
496 the compilation system, are presumed to have already been stripped from
497 MANGLED. */
499 char *
500 cplus_demangle (mangled, options)
501 const char *mangled;
502 int options;
504 string decl;
505 int success = 0;
506 struct work_stuff work[1];
507 char *demangled = NULL;
509 if ((mangled != NULL) && (*mangled != '\0'))
511 memset ((char *) work, 0, sizeof (work));
512 work -> options = options;
513 if ((work->options & DMGL_STYLE_MASK) == 0)
514 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
516 string_init (&decl);
518 /* First check to see if gnu style demangling is active and if the
519 string to be demangled contains a CPLUS_MARKER. If so, attempt to
520 recognize one of the gnu special forms rather than looking for a
521 standard prefix. In particular, don't worry about whether there
522 is a "__" string in the mangled string. Consider "_$_5__foo" for
523 example. */
525 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
527 success = gnu_special (work, &mangled, &decl);
529 if (!success)
531 success = demangle_prefix (work, &mangled, &decl);
533 if (success && (*mangled != '\0'))
535 success = demangle_signature (work, &mangled, &decl);
537 if (work->constructor == 2)
539 string_prepend(&decl, "global constructors keyed to ");
540 work->constructor = 0;
542 else if (work->destructor == 2)
544 string_prepend(&decl, "global destructors keyed to ");
545 work->destructor = 0;
547 demangled = mop_up (work, &decl, success);
549 return (demangled);
552 static char *
553 mop_up (work, declp, success)
554 struct work_stuff *work;
555 string *declp;
556 int success;
558 char *demangled = NULL;
560 /* Discard the remembered types, if any. */
562 forget_types (work);
563 if (work -> typevec != NULL)
565 free ((char *) work -> typevec);
568 /* If demangling was successful, ensure that the demangled string is null
569 terminated and return it. Otherwise, free the demangling decl. */
571 if (!success)
573 string_delete (declp);
575 else
577 string_appendn (declp, "", 1);
578 demangled = declp -> b;
580 return (demangled);
585 LOCAL FUNCTION
587 demangle_signature -- demangle the signature part of a mangled name
589 SYNOPSIS
591 static int
592 demangle_signature (struct work_stuff *work, const char **mangled,
593 string *declp);
595 DESCRIPTION
597 Consume and demangle the signature portion of the mangled name.
599 DECLP is the string where demangled output is being built. At
600 entry it contains the demangled root name from the mangled name
601 prefix. I.E. either a demangled operator name or the root function
602 name. In some special cases, it may contain nothing.
604 *MANGLED points to the current unconsumed location in the mangled
605 name. As tokens are consumed and demangling is performed, the
606 pointer is updated to continuously point at the next token to
607 be consumed.
609 Demangling GNU style mangled names is nasty because there is no
610 explicit token that marks the start of the outermost function
611 argument list.
614 static int
615 demangle_signature (work, mangled, declp)
616 struct work_stuff *work;
617 const char **mangled;
618 string *declp;
620 int success = 1;
621 int func_done = 0;
622 int expect_func = 0;
623 const char *oldmangled = NULL;
624 string trawname;
625 string tname;
627 while (success && (**mangled != '\0'))
629 switch (**mangled)
631 case 'Q':
632 oldmangled = *mangled;
633 success = demangle_qualified (work, mangled, declp, 1, 0);
634 if (success)
636 remember_type (work, oldmangled, *mangled - oldmangled);
638 if (AUTO_DEMANGLING || GNU_DEMANGLING)
640 expect_func = 1;
642 oldmangled = NULL;
643 break;
645 case 'S':
646 /* Static member function */
647 if (oldmangled == NULL)
649 oldmangled = *mangled;
651 (*mangled)++;
652 work -> static_type = 1;
653 break;
655 case 'C':
656 /* a const member function */
657 if (oldmangled == NULL)
659 oldmangled = *mangled;
661 (*mangled)++;
662 work -> const_type = 1;
663 break;
665 case '0': case '1': case '2': case '3': case '4':
666 case '5': case '6': case '7': case '8': case '9':
667 if (oldmangled == NULL)
669 oldmangled = *mangled;
671 success = demangle_class (work, mangled, declp);
672 if (success)
674 remember_type (work, oldmangled, *mangled - oldmangled);
676 if (AUTO_DEMANGLING || GNU_DEMANGLING)
678 expect_func = 1;
680 oldmangled = NULL;
681 break;
683 case 'F':
684 /* Function */
685 /* ARM style demangling includes a specific 'F' character after
686 the class name. For GNU style, it is just implied. So we can
687 safely just consume any 'F' at this point and be compatible
688 with either style. */
690 oldmangled = NULL;
691 func_done = 1;
692 (*mangled)++;
694 /* For lucid/ARM style we have to forget any types we might
695 have remembered up to this point, since they were not argument
696 types. GNU style considers all types seen as available for
697 back references. See comment in demangle_args() */
699 if (LUCID_DEMANGLING || ARM_DEMANGLING)
701 forget_types (work);
703 success = demangle_args (work, mangled, declp);
704 break;
706 case 't':
707 /* G++ Template */
708 string_init(&trawname);
709 string_init(&tname);
710 if (oldmangled == NULL)
712 oldmangled = *mangled;
714 success = demangle_template (work, mangled, &tname, &trawname);
715 if (success)
717 remember_type (work, oldmangled, *mangled - oldmangled);
719 string_append(&tname, "::");
720 string_prepends(declp, &tname);
721 if (work -> destructor & 1)
723 string_prepend (&trawname, "~");
724 string_appends (declp, &trawname);
725 work->destructor -= 1;
727 if ((work->constructor & 1) || (work->destructor & 1))
729 string_appends (declp, &trawname);
730 work->constructor -= 1;
732 string_delete(&trawname);
733 string_delete(&tname);
734 oldmangled = NULL;
735 expect_func = 1;
736 break;
738 case '_':
739 /* At the outermost level, we cannot have a return type specified,
740 so if we run into another '_' at this point we are dealing with
741 a mangled name that is either bogus, or has been mangled by
742 some algorithm we don't know how to deal with. So just
743 reject the entire demangling. */
744 success = 0;
745 break;
747 default:
748 if (AUTO_DEMANGLING || GNU_DEMANGLING)
750 /* Assume we have stumbled onto the first outermost function
751 argument token, and start processing args. */
752 func_done = 1;
753 success = demangle_args (work, mangled, declp);
755 else
757 /* Non-GNU demanglers use a specific token to mark the start
758 of the outermost function argument tokens. Typically 'F',
759 for ARM-demangling, for example. So if we find something
760 we are not prepared for, it must be an error. */
761 success = 0;
763 break;
766 if (AUTO_DEMANGLING || GNU_DEMANGLING)
769 if (success && expect_func)
771 func_done = 1;
772 success = demangle_args (work, mangled, declp);
776 if (success && !func_done)
778 if (AUTO_DEMANGLING || GNU_DEMANGLING)
780 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
781 bar__3fooi is 'foo::bar(int)'. We get here when we find the
782 first case, and need to ensure that the '(void)' gets added to
783 the current declp. Note that with ARM, the first case
784 represents the name of a static data member 'foo::bar',
785 which is in the current declp, so we leave it alone. */
786 success = demangle_args (work, mangled, declp);
789 if (success && work -> static_type && PRINT_ARG_TYPES)
791 string_append (declp, " static");
793 if (success && work -> const_type && PRINT_ARG_TYPES)
795 string_append (declp, " const");
797 return (success);
800 #if 0
802 static int
803 demangle_method_args (work, mangled, declp)
804 struct work_stuff *work;
805 const char **mangled;
806 string *declp;
808 int success = 0;
810 if (work -> static_type)
812 string_append (declp, *mangled + 1);
813 *mangled += strlen (*mangled);
814 success = 1;
816 else
818 success = demangle_args (work, mangled, declp);
820 return (success);
823 #endif
825 static int
826 demangle_template (work, mangled, tname, trawname)
827 struct work_stuff *work;
828 const char **mangled;
829 string *tname;
830 string *trawname;
832 int i;
833 int is_pointer;
834 int is_real;
835 int is_integral;
836 int is_char;
837 int is_bool;
838 int r;
839 int need_comma = 0;
840 int success = 0;
841 int done;
842 const char *old_p;
843 const char *start;
844 int symbol_len;
845 string temp;
847 (*mangled)++;
848 start = *mangled;
849 /* get template name */
850 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
852 return (0);
854 if (trawname)
855 string_appendn (trawname, *mangled, r);
856 string_appendn (tname, *mangled, r);
857 *mangled += r;
858 string_append (tname, "<");
859 /* get size of template parameter list */
860 if (!get_count (mangled, &r))
862 return (0);
864 for (i = 0; i < r; i++)
866 if (need_comma)
868 string_append (tname, ", ");
870 /* Z for type parameters */
871 if (**mangled == 'Z')
873 (*mangled)++;
874 /* temp is initialized in do_type */
875 success = do_type (work, mangled, &temp);
876 if (success)
878 string_appends (tname, &temp);
880 string_delete(&temp);
881 if (!success)
883 break;
886 else
888 /* otherwise, value parameter */
889 old_p = *mangled;
890 is_pointer = 0;
891 is_real = 0;
892 is_integral = 0;
893 is_char = 0;
894 done = 0;
895 /* temp is initialized in do_type */
896 success = do_type (work, mangled, &temp);
898 if (success)
900 string_appends (tname, &temp);
903 string_delete(&temp);
904 if (!success)
906 break;
909 string_append (tname, "=");
911 while (*old_p && !done)
913 switch (*old_p)
915 case 'P':
916 case 'p':
917 case 'R':
918 done = is_pointer = 1;
919 break;
920 case 'C': /* const */
921 case 'S': /* explicitly signed [char] */
922 case 'U': /* unsigned */
923 case 'V': /* volatile */
924 case 'F': /* function */
925 case 'M': /* member function */
926 case 'O': /* ??? */
927 old_p++;
928 continue;
929 case 'Q': /* qualified name */
930 done = is_integral = 1;
931 break;
932 case 'T': /* remembered type */
933 abort ();
934 break;
935 case 'v': /* void */
936 abort ();
937 break;
938 case 'x': /* long long */
939 case 'l': /* long */
940 case 'i': /* int */
941 case 's': /* short */
942 case 'w': /* wchar_t */
943 done = is_integral = 1;
944 break;
945 case 'b': /* bool */
946 done = is_bool = 1;
947 break;
948 case 'c': /* char */
949 done = is_char = 1;
950 break;
951 case 'r': /* long double */
952 case 'd': /* double */
953 case 'f': /* float */
954 done = is_real = 1;
955 break;
956 default:
957 /* it's probably user defined type, let's assume
958 it's integeral, it seems hard to figure out
959 what it really is */
960 done = is_integral = 1;
963 if (is_integral)
965 if (**mangled == 'm')
967 string_appendn (tname, "-", 1);
968 (*mangled)++;
970 while (isdigit (**mangled))
972 string_appendn (tname, *mangled, 1);
973 (*mangled)++;
976 else if (is_char)
978 char tmp[2];
979 int val;
980 if (**mangled == 'm')
982 string_appendn (tname, "-", 1);
983 (*mangled)++;
985 string_appendn (tname, "'", 1);
986 val = consume_count(mangled);
987 if (val == 0)
989 success = 0;
990 break;
992 tmp[0] = (char)val;
993 tmp[1] = '\0';
994 string_appendn (tname, &tmp[0], 1);
995 string_appendn (tname, "'", 1);
997 else if (is_bool)
999 int val = consume_count (mangled);
1000 if (val == 0)
1001 string_appendn (tname, "false", 5);
1002 else if (val == 1)
1003 string_appendn (tname, "true", 4);
1004 else
1005 success = 0;
1007 else if (is_real)
1009 if (**mangled == 'm')
1011 string_appendn (tname, "-", 1);
1012 (*mangled)++;
1014 while (isdigit (**mangled))
1016 string_appendn (tname, *mangled, 1);
1017 (*mangled)++;
1019 if (**mangled == '.') /* fraction */
1021 string_appendn (tname, ".", 1);
1022 (*mangled)++;
1023 while (isdigit (**mangled))
1025 string_appendn (tname, *mangled, 1);
1026 (*mangled)++;
1029 if (**mangled == 'e') /* exponent */
1031 string_appendn (tname, "e", 1);
1032 (*mangled)++;
1033 while (isdigit (**mangled))
1035 string_appendn (tname, *mangled, 1);
1036 (*mangled)++;
1040 else if (is_pointer)
1042 if (!get_count (mangled, &symbol_len))
1044 success = 0;
1045 break;
1047 string_appendn (tname, *mangled, symbol_len);
1048 *mangled += symbol_len;
1051 need_comma = 1;
1053 if (tname->p[-1] == '>')
1054 string_append (tname, " ");
1055 string_append (tname, ">");
1058 if (work -> static_type)
1060 string_append (declp, *mangled + 1);
1061 *mangled += strlen (*mangled);
1062 success = 1;
1064 else
1066 success = demangle_args (work, mangled, declp);
1070 return (success);
1073 static int
1074 arm_pt (work, mangled, n, anchor, args)
1075 struct work_stuff *work;
1076 const char *mangled;
1077 int n;
1078 const char **anchor, **args;
1080 /* ARM template? */
1081 if (ARM_DEMANGLING && (*anchor = strstr(mangled, "__pt__")))
1083 int len;
1084 *args = *anchor + 6;
1085 len = consume_count (args);
1086 if (*args + len == mangled + n && **args == '_')
1088 ++*args;
1089 return 1;
1092 return 0;
1095 static void
1096 demangle_arm_pt (work, mangled, n, declp)
1097 struct work_stuff *work;
1098 const char **mangled;
1099 int n;
1100 string *declp;
1102 const char *p;
1103 const char *args;
1104 const char *e = *mangled + n;
1106 /* ARM template? */
1107 if (arm_pt (work, *mangled, n, &p, &args))
1109 string arg;
1110 string_init (&arg);
1111 string_appendn (declp, *mangled, p - *mangled);
1112 string_append (declp, "<");
1113 /* should do error checking here */
1114 while (args < e) {
1115 string_clear (&arg);
1116 do_type (work, &args, &arg);
1117 string_appends (declp, &arg);
1118 string_append (declp, ",");
1120 string_delete (&arg);
1121 --declp->p;
1122 string_append (declp, ">");
1124 else
1126 string_appendn (declp, *mangled, n);
1128 *mangled += n;
1131 static int
1132 demangle_class_name (work, mangled, declp)
1133 struct work_stuff *work;
1134 const char **mangled;
1135 string *declp;
1137 int n;
1138 int success = 0;
1140 n = consume_count (mangled);
1141 if (strlen (*mangled) >= n)
1143 demangle_arm_pt (work, mangled, n, declp);
1144 success = 1;
1147 return (success);
1152 LOCAL FUNCTION
1154 demangle_class -- demangle a mangled class sequence
1156 SYNOPSIS
1158 static int
1159 demangle_class (struct work_stuff *work, const char **mangled,
1160 strint *declp)
1162 DESCRIPTION
1164 DECLP points to the buffer into which demangling is being done.
1166 *MANGLED points to the current token to be demangled. On input,
1167 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1168 On exit, it points to the next token after the mangled class on
1169 success, or the first unconsumed token on failure.
1171 If the constRUCTOR or DESTRUCTOR flags are set in WORK, then
1172 we are demangling a constructor or destructor. In this case
1173 we prepend "class::class" or "class::~class" to DECLP.
1175 Otherwise, we prepend "class::" to the current DECLP.
1177 Reset the constructor/destructor flags once they have been
1178 "consumed". This allows demangle_class to be called later during
1179 the same demangling, to do normal class demangling.
1181 Returns 1 if demangling is successful, 0 otherwise.
1185 static int
1186 demangle_class (work, mangled, declp)
1187 struct work_stuff *work;
1188 const char **mangled;
1189 string *declp;
1191 int success = 0;
1192 string class_name;
1194 string_init (&class_name);
1195 if (demangle_class_name (work, mangled, &class_name))
1197 if ((work->constructor & 1) || (work->destructor & 1))
1199 string_prepends (declp, &class_name);
1200 if (work -> destructor & 1)
1202 string_prepend (declp, "~");
1203 work -> destructor -= 1;
1205 else
1207 work -> constructor -= 1;
1210 string_prepend (declp, "::");
1211 string_prepends (declp, &class_name);
1212 success = 1;
1214 string_delete (&class_name);
1215 return (success);
1220 LOCAL FUNCTION
1222 demangle_prefix -- consume the mangled name prefix and find signature
1224 SYNOPSIS
1226 static int
1227 demangle_prefix (struct work_stuff *work, const char **mangled,
1228 string *declp);
1230 DESCRIPTION
1232 Consume and demangle the prefix of the mangled name.
1234 DECLP points to the string buffer into which demangled output is
1235 placed. On entry, the buffer is empty. On exit it contains
1236 the root function name, the demangled operator name, or in some
1237 special cases either nothing or the completely demangled result.
1239 MANGLED points to the current pointer into the mangled name. As each
1240 token of the mangled name is consumed, it is updated. Upon entry
1241 the current mangled name pointer points to the first character of
1242 the mangled name. Upon exit, it should point to the first character
1243 of the signature if demangling was successful, or to the first
1244 unconsumed character if demangling of the prefix was unsuccessful.
1246 Returns 1 on success, 0 otherwise.
1249 static int
1250 demangle_prefix (work, mangled, declp)
1251 struct work_stuff *work;
1252 const char **mangled;
1253 string *declp;
1255 int success = 1;
1256 const char *scan;
1257 int i;
1259 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1261 char *marker = strchr (cplus_markers, (*mangled)[8]);
1262 if (marker != NULL && *marker == (*mangled)[10])
1264 if ((*mangled)[9] == 'D')
1266 /* it's a GNU global destructor to be executed at program exit */
1267 (*mangled) += 11;
1268 work->destructor = 2;
1269 if (gnu_special (work, mangled, declp))
1270 return success;
1272 else if ((*mangled)[9] == 'I')
1274 /* it's a GNU global constructor to be executed at program init */
1275 (*mangled) += 11;
1276 work->constructor = 2;
1277 if (gnu_special (work, mangled, declp))
1278 return success;
1282 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1284 /* it's a ARM global destructor to be executed at program exit */
1285 (*mangled) += 7;
1286 work->destructor = 2;
1288 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1290 /* it's a ARM global constructor to be executed at program initial */
1291 (*mangled) += 7;
1292 work->constructor = 2;
1295 /* This block of code is a reduction in strength time optimization
1297 scan = strstr (*mangled, "__"); */
1300 scan = *mangled;
1302 do {
1303 scan = strchr (scan, '_');
1304 } while (scan != NULL && *++scan != '_');
1306 if (scan != NULL) --scan;
1309 if (scan != NULL)
1311 /* We found a sequence of two or more '_', ensure that we start at
1312 the last pair in the sequence. */
1313 i = strspn (scan, "_");
1314 if (i > 2)
1316 scan += (i - 2);
1320 if (scan == NULL)
1322 success = 0;
1324 else if (work -> static_type)
1326 if (!isdigit (scan[0]) && (scan[0] != 't'))
1328 success = 0;
1331 else if ((scan == *mangled) &&
1332 (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
1334 /* The ARM says nothing about the mangling of local variables.
1335 But cfront mangles local variables by prepending __<nesting_level>
1336 to them. As an extension to ARM demangling we handle this case. */
1337 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1339 *mangled = scan + 2;
1340 consume_count (mangled);
1341 string_append (declp, *mangled);
1342 *mangled += strlen (*mangled);
1343 success = 1;
1345 else
1347 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1348 names like __Q2_3foo3bar for nested type names. So don't accept
1349 this style of constructor for cfront demangling. */
1350 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1351 work -> constructor += 1;
1352 *mangled = scan + 2;
1355 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1357 /* Mangled name starts with "__". Skip over any leading '_' characters,
1358 then find the next "__" that separates the prefix from the signature.
1360 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1361 || (arm_special (work, mangled, declp) == 0))
1363 while (*scan == '_')
1365 scan++;
1367 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1369 /* No separator (I.E. "__not_mangled"), or empty signature
1370 (I.E. "__not_mangled_either__") */
1371 success = 0;
1373 else
1375 demangle_function_name (work, mangled, declp, scan);
1379 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1381 /* Cfront-style parameterized type. Handled later as a signature. */
1382 success = 1;
1384 /* ARM template? */
1385 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1387 else if (*(scan + 2) != '\0')
1389 /* Mangled name does not start with "__" but does have one somewhere
1390 in there with non empty stuff after it. Looks like a global
1391 function name. */
1392 demangle_function_name (work, mangled, declp, scan);
1394 else
1396 /* Doesn't look like a mangled name */
1397 success = 0;
1400 if (!success && (work->constructor == 2 || work->destructor == 2))
1402 string_append (declp, *mangled);
1403 *mangled += strlen (*mangled);
1404 success = 1;
1406 return (success);
1411 LOCAL FUNCTION
1413 gnu_special -- special handling of gnu mangled strings
1415 SYNOPSIS
1417 static int
1418 gnu_special (struct work_stuff *work, const char **mangled,
1419 string *declp);
1422 DESCRIPTION
1424 Process some special GNU style mangling forms that don't fit
1425 the normal pattern. For example:
1427 _$_3foo (destructor for class foo)
1428 _vt$foo (foo virtual table)
1429 _vt$foo$bar (foo::bar virtual table)
1430 __vt_foo (foo virtual table, new style with thunks)
1431 _3foo$varname (static data member)
1432 _Q22rs2tu$vw (static data member)
1433 __t6vector1Zii (constructor with template)
1434 __thunk_4__$_7ostream (virtual function thunk)
1437 static int
1438 gnu_special (work, mangled, declp)
1439 struct work_stuff *work;
1440 const char **mangled;
1441 string *declp;
1443 int n;
1444 int success = 1;
1445 const char *p;
1447 if ((*mangled)[0] == '_'
1448 && strchr (cplus_markers, (*mangled)[1]) != NULL
1449 && (*mangled)[2] == '_')
1451 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1452 (*mangled) += 3;
1453 work -> destructor += 1;
1455 else if ((*mangled)[0] == '_'
1456 && (((*mangled)[1] == '_'
1457 && (*mangled)[2] == 'v'
1458 && (*mangled)[3] == 't'
1459 && (*mangled)[4] == '_')
1460 || ((*mangled)[1] == 'v'
1461 && (*mangled)[2] == 't'
1462 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1464 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1465 and create the decl. Note that we consume the entire mangled
1466 input string, which means that demangle_signature has no work
1467 to do. */
1468 if ((*mangled)[2] == 'v')
1469 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1470 else
1471 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1472 while (**mangled != '\0')
1474 p = strpbrk (*mangled, cplus_markers);
1475 switch (**mangled)
1477 case 'Q':
1478 success = demangle_qualified (work, mangled, declp, 0, 1);
1479 break;
1480 case 't':
1481 success = demangle_template (work, mangled, declp, 0);
1482 break;
1483 default:
1484 if (isdigit(*mangled[0]))
1486 n = consume_count(mangled);
1488 else
1490 n = strcspn (*mangled, cplus_markers);
1492 string_appendn (declp, *mangled, n);
1493 (*mangled) += n;
1496 if (success && ((p == NULL) || (p == *mangled)))
1498 if (p != NULL)
1500 string_append (declp, "::");
1501 (*mangled)++;
1504 else
1506 success = 0;
1507 break;
1510 if (success)
1511 string_append (declp, " virtual table");
1513 else if ((*mangled)[0] == '_'
1514 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1515 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1517 /* static data member, "_3foo$varname" for example */
1518 (*mangled)++;
1519 switch (**mangled)
1521 case 'Q':
1522 success = demangle_qualified (work, mangled, declp, 0, 1);
1523 break;
1524 case 't':
1525 success = demangle_template (work, mangled, declp, 0);
1526 break;
1527 default:
1528 n = consume_count (mangled);
1529 string_appendn (declp, *mangled, n);
1530 (*mangled) += n;
1532 if (success && (p == *mangled))
1534 /* Consumed everything up to the cplus_marker, append the
1535 variable name. */
1536 (*mangled)++;
1537 string_append (declp, "::");
1538 n = strlen (*mangled);
1539 string_appendn (declp, *mangled, n);
1540 (*mangled) += n;
1542 else
1544 success = 0;
1547 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1549 int delta = ((*mangled) += 8, consume_count (mangled));
1550 char *method = cplus_demangle (++*mangled, work->options);
1551 if (method)
1553 char buf[50];
1554 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1555 string_append (declp, buf);
1556 string_append (declp, method);
1557 free (method);
1558 n = strlen (*mangled);
1559 (*mangled) += n;
1561 else
1563 success = 0;
1566 else
1568 success = 0;
1570 return (success);
1575 LOCAL FUNCTION
1577 arm_special -- special handling of ARM/lucid mangled strings
1579 SYNOPSIS
1581 static int
1582 arm_special (struct work_stuff *work, const char **mangled,
1583 string *declp);
1586 DESCRIPTION
1588 Process some special ARM style mangling forms that don't fit
1589 the normal pattern. For example:
1591 __vtbl__3foo (foo virtual table)
1592 __vtbl__3foo__3bar (bar::foo virtual table)
1596 static int
1597 arm_special (work, mangled, declp)
1598 struct work_stuff *work;
1599 const char **mangled;
1600 string *declp;
1602 int n;
1603 int success = 1;
1604 const char *scan;
1606 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1608 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1609 and create the decl. Note that we consume the entire mangled
1610 input string, which means that demangle_signature has no work
1611 to do. */
1612 scan = *mangled + ARM_VTABLE_STRLEN;
1613 while (*scan != '\0') /* first check it can be demangled */
1615 n = consume_count (&scan);
1616 if (n==0)
1618 return (0); /* no good */
1620 scan += n;
1621 if (scan[0] == '_' && scan[1] == '_')
1623 scan += 2;
1626 (*mangled) += ARM_VTABLE_STRLEN;
1627 while (**mangled != '\0')
1629 n = consume_count (mangled);
1630 string_prependn (declp, *mangled, n);
1631 (*mangled) += n;
1632 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1634 string_prepend (declp, "::");
1635 (*mangled) += 2;
1638 string_append (declp, " virtual table");
1640 else
1642 success = 0;
1644 return (success);
1649 LOCAL FUNCTION
1651 demangle_qualified -- demangle 'Q' qualified name strings
1653 SYNOPSIS
1655 static int
1656 demangle_qualified (struct work_stuff *, const char *mangled,
1657 string *result, int isfuncname, int append);
1659 DESCRIPTION
1661 Demangle a qualified name, such as "Q25Outer5Inner" which is
1662 the mangled form of "Outer::Inner". The demangled output is
1663 prepended or appended to the result string according to the
1664 state of the append flag.
1666 If isfuncname is nonzero, then the qualified name we are building
1667 is going to be used as a member function name, so if it is a
1668 constructor or destructor function, append an appropriate
1669 constructor or destructor name. I.E. for the above example,
1670 the result for use as a constructor is "Outer::Inner::Inner"
1671 and the result for use as a destructor is "Outer::Inner::~Inner".
1673 BUGS
1675 Numeric conversion is ASCII dependent (FIXME).
1679 static int
1680 demangle_qualified (work, mangled, result, isfuncname, append)
1681 struct work_stuff *work;
1682 const char **mangled;
1683 string *result;
1684 int isfuncname;
1685 int append;
1687 int qualifiers;
1688 int namelength;
1689 int success = 1;
1690 const char *p;
1691 char num[2];
1692 string temp;
1694 string_init (&temp);
1695 switch ((*mangled)[1])
1697 case '_':
1698 /* GNU mangled name with more than 9 classes. The count is preceded
1699 by an underscore (to distinguish it from the <= 9 case) and followed
1700 by an underscore. */
1701 p = *mangled + 2;
1702 qualifiers = atoi (p);
1703 if (!isdigit (*p) || *p == '0')
1704 success = 0;
1706 /* Skip the digits. */
1707 while (isdigit (*p))
1708 ++p;
1710 if (*p != '_')
1711 success = 0;
1713 *mangled = p + 1;
1714 break;
1716 case '1':
1717 case '2':
1718 case '3':
1719 case '4':
1720 case '5':
1721 case '6':
1722 case '7':
1723 case '8':
1724 case '9':
1725 /* The count is in a single digit. */
1726 num[0] = (*mangled)[1];
1727 num[1] = '\0';
1728 qualifiers = atoi (num);
1730 /* If there is an underscore after the digit, skip it. This is
1731 said to be for ARM-qualified names, but the ARM makes no
1732 mention of such an underscore. Perhaps cfront uses one. */
1733 if ((*mangled)[2] == '_')
1735 (*mangled)++;
1737 (*mangled) += 2;
1738 break;
1740 case '0':
1741 default:
1742 success = 0;
1745 if (!success)
1746 return success;
1748 /* Pick off the names and collect them in the temp buffer in the order
1749 in which they are found, separated by '::'. */
1751 while (qualifiers-- > 0)
1753 if (*mangled[0] == '_')
1754 *mangled = *mangled + 1;
1755 if (*mangled[0] == 't')
1757 success = demangle_template(work, mangled, &temp, 0);
1758 if (!success) break;
1760 else
1762 namelength = consume_count (mangled);
1763 if (strlen (*mangled) < namelength)
1765 /* Simple sanity check failed */
1766 success = 0;
1767 break;
1769 string_appendn (&temp, *mangled, namelength);
1770 *mangled += namelength;
1772 if (qualifiers > 0)
1774 string_appendn (&temp, "::", 2);
1778 /* If we are using the result as a function name, we need to append
1779 the appropriate '::' separated constructor or destructor name.
1780 We do this here because this is the most convenient place, where
1781 we already have a pointer to the name and the length of the name. */
1783 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1785 string_appendn (&temp, "::", 2);
1786 if (work -> destructor & 1)
1788 string_append (&temp, "~");
1790 string_appendn (&temp, (*mangled) - namelength, namelength);
1793 /* Now either prepend the temp buffer to the result, or append it,
1794 depending upon the state of the append flag. */
1796 if (append)
1798 string_appends (result, &temp);
1800 else
1802 if (!STRING_EMPTY (result))
1804 string_appendn (&temp, "::", 2);
1806 string_prepends (result, &temp);
1809 string_delete (&temp);
1810 return (success);
1815 LOCAL FUNCTION
1817 get_count -- convert an ascii count to integer, consuming tokens
1819 SYNOPSIS
1821 static int
1822 get_count (const char **type, int *count)
1824 DESCRIPTION
1826 Return 0 if no conversion is performed, 1 if a string is converted.
1829 static int
1830 get_count (type, count)
1831 const char **type;
1832 int *count;
1834 const char *p;
1835 int n;
1837 if (!isdigit (**type))
1839 return (0);
1841 else
1843 *count = **type - '0';
1844 (*type)++;
1845 if (isdigit (**type))
1847 p = *type;
1848 n = *count;
1851 n *= 10;
1852 n += *p - '0';
1853 p++;
1855 while (isdigit (*p));
1856 if (*p == '_')
1858 *type = p + 1;
1859 *count = n;
1863 return (1);
1866 /* result will be initialised here; it will be freed on failure */
1868 static int
1869 do_type (work, mangled, result)
1870 struct work_stuff *work;
1871 const char **mangled;
1872 string *result;
1874 int n;
1875 int done;
1876 int success;
1877 string decl;
1878 const char *remembered_type;
1879 int constp;
1880 int volatilep;
1882 string_init (&decl);
1883 string_init (result);
1885 done = 0;
1886 success = 1;
1887 while (success && !done)
1889 int member;
1890 switch (**mangled)
1893 /* A pointer type */
1894 case 'P':
1895 case 'p':
1896 (*mangled)++;
1897 string_prepend (&decl, "*");
1898 break;
1900 /* A reference type */
1901 case 'R':
1902 (*mangled)++;
1903 string_prepend (&decl, "&");
1904 break;
1906 /* An array */
1907 case 'A':
1909 const char *p = ++(*mangled);
1911 string_prepend (&decl, "(");
1912 string_append (&decl, ")[");
1913 /* Copy anything up until the next underscore (the size of the
1914 array). */
1915 while (**mangled && **mangled != '_')
1916 ++(*mangled);
1917 if (**mangled == '_')
1919 string_appendn (&decl, p, *mangled - p);
1920 string_append (&decl, "]");
1921 *mangled += 1;
1923 else
1924 success = 0;
1925 break;
1928 /* A back reference to a previously seen type */
1929 case 'T':
1930 (*mangled)++;
1931 if (!get_count (mangled, &n) || n >= work -> ntypes)
1933 success = 0;
1935 else
1937 remembered_type = work -> typevec[n];
1938 mangled = &remembered_type;
1940 break;
1942 /* A function */
1943 case 'F':
1944 (*mangled)++;
1945 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
1947 string_prepend (&decl, "(");
1948 string_append (&decl, ")");
1950 /* After picking off the function args, we expect to either find the
1951 function return type (preceded by an '_') or the end of the
1952 string. */
1953 if (!demangle_args (work, mangled, &decl)
1954 || (**mangled != '_' && **mangled != '\0'))
1956 success = 0;
1958 if (success && (**mangled == '_'))
1960 (*mangled)++;
1962 break;
1964 case 'M':
1965 case 'O':
1967 constp = 0;
1968 volatilep = 0;
1970 member = **mangled == 'M';
1971 (*mangled)++;
1972 if (!isdigit (**mangled))
1974 success = 0;
1975 break;
1977 n = consume_count (mangled);
1978 if (strlen (*mangled) < n)
1980 success = 0;
1981 break;
1983 string_append (&decl, ")");
1984 string_prepend (&decl, "::");
1985 string_prependn (&decl, *mangled, n);
1986 string_prepend (&decl, "(");
1987 *mangled += n;
1988 if (member)
1990 if (**mangled == 'C')
1992 (*mangled)++;
1993 constp = 1;
1995 if (**mangled == 'V')
1997 (*mangled)++;
1998 volatilep = 1;
2000 if (*(*mangled)++ != 'F')
2002 success = 0;
2003 break;
2006 if ((member && !demangle_args (work, mangled, &decl))
2007 || **mangled != '_')
2009 success = 0;
2010 break;
2012 (*mangled)++;
2013 if (! PRINT_ANSI_QUALIFIERS)
2015 break;
2017 if (constp)
2019 APPEND_BLANK (&decl);
2020 string_append (&decl, "const");
2022 if (volatilep)
2024 APPEND_BLANK (&decl);
2025 string_append (&decl, "volatile");
2027 break;
2029 case 'G':
2030 (*mangled)++;
2031 break;
2033 case 'C':
2034 (*mangled)++;
2036 if ((*mangled)[1] == 'P')
2039 if (PRINT_ANSI_QUALIFIERS)
2041 if (!STRING_EMPTY (&decl))
2043 string_prepend (&decl, " ");
2045 string_prepend (&decl, "const");
2047 break;
2052 /* fall through */
2053 default:
2054 done = 1;
2055 break;
2059 switch (**mangled)
2061 /* A qualified name, such as "Outer::Inner". */
2062 case 'Q':
2063 success = demangle_qualified (work, mangled, result, 0, 1);
2064 break;
2066 default:
2067 success = demangle_fund_type (work, mangled, result);
2068 break;
2071 if (success)
2073 if (!STRING_EMPTY (&decl))
2075 string_append (result, " ");
2076 string_appends (result, &decl);
2079 else
2081 string_delete (result);
2083 string_delete (&decl);
2084 return (success);
2087 /* Given a pointer to a type string that represents a fundamental type
2088 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2089 string in which the demangled output is being built in RESULT, and
2090 the WORK structure, decode the types and add them to the result.
2092 For example:
2094 "Ci" => "const int"
2095 "Sl" => "signed long"
2096 "CUs" => "const unsigned short"
2100 static int
2101 demangle_fund_type (work, mangled, result)
2102 struct work_stuff *work;
2103 const char **mangled;
2104 string *result;
2106 int done = 0;
2107 int success = 1;
2109 /* First pick off any type qualifiers. There can be more than one. */
2111 while (!done)
2113 switch (**mangled)
2115 case 'C':
2116 (*mangled)++;
2117 if (PRINT_ANSI_QUALIFIERS)
2119 APPEND_BLANK (result);
2120 string_append (result, "const");
2122 break;
2123 case 'U':
2124 (*mangled)++;
2125 APPEND_BLANK (result);
2126 string_append (result, "unsigned");
2127 break;
2128 case 'S': /* signed char only */
2129 (*mangled)++;
2130 APPEND_BLANK (result);
2131 string_append (result, "signed");
2132 break;
2133 case 'V':
2134 (*mangled)++;
2135 if (PRINT_ANSI_QUALIFIERS)
2137 APPEND_BLANK (result);
2138 string_append (result, "volatile");
2140 break;
2141 default:
2142 done = 1;
2143 break;
2147 /* Now pick off the fundamental type. There can be only one. */
2149 switch (**mangled)
2151 case '\0':
2152 case '_':
2153 break;
2154 case 'v':
2155 (*mangled)++;
2156 APPEND_BLANK (result);
2157 string_append (result, "void");
2158 break;
2159 case 'x':
2160 (*mangled)++;
2161 APPEND_BLANK (result);
2162 string_append (result, "long long");
2163 break;
2164 case 'l':
2165 (*mangled)++;
2166 APPEND_BLANK (result);
2167 string_append (result, "long");
2168 break;
2169 case 'i':
2170 (*mangled)++;
2171 APPEND_BLANK (result);
2172 string_append (result, "int");
2173 break;
2174 case 's':
2175 (*mangled)++;
2176 APPEND_BLANK (result);
2177 string_append (result, "short");
2178 break;
2179 case 'b':
2180 (*mangled)++;
2181 APPEND_BLANK (result);
2182 string_append (result, "bool");
2183 break;
2184 case 'c':
2185 (*mangled)++;
2186 APPEND_BLANK (result);
2187 string_append (result, "char");
2188 break;
2189 case 'w':
2190 (*mangled)++;
2191 APPEND_BLANK (result);
2192 string_append (result, "wchar_t");
2193 break;
2194 case 'r':
2195 (*mangled)++;
2196 APPEND_BLANK (result);
2197 string_append (result, "long double");
2198 break;
2199 case 'd':
2200 (*mangled)++;
2201 APPEND_BLANK (result);
2202 string_append (result, "double");
2203 break;
2204 case 'f':
2205 (*mangled)++;
2206 APPEND_BLANK (result);
2207 string_append (result, "float");
2208 break;
2209 case 'G':
2210 (*mangled)++;
2211 if (!isdigit (**mangled))
2213 success = 0;
2214 break;
2216 /* fall through */
2217 /* An explicit type, such as "6mytype" or "7integer" */
2218 case '0':
2219 case '1':
2220 case '2':
2221 case '3':
2222 case '4':
2223 case '5':
2224 case '6':
2225 case '7':
2226 case '8':
2227 case '9':
2228 APPEND_BLANK (result);
2229 if (!demangle_class_name (work, mangled, result)) {
2230 --result->p;
2231 success = 0;
2233 break;
2234 case 't':
2235 success = demangle_template(work,mangled, result, 0);
2236 break;
2237 default:
2238 success = 0;
2239 break;
2242 return (success);
2245 /* `result' will be initialized in do_type; it will be freed on failure */
2247 static int
2248 do_arg (work, mangled, result)
2249 struct work_stuff *work;
2250 const char **mangled;
2251 string *result;
2253 const char *start = *mangled;
2255 if (!do_type (work, mangled, result))
2257 return (0);
2259 else
2261 remember_type (work, start, *mangled - start);
2262 return (1);
2266 static void
2267 remember_type (work, start, len)
2268 struct work_stuff *work;
2269 const char *start;
2270 int len;
2272 char *tem;
2274 if (work -> ntypes >= work -> typevec_size)
2276 if (work -> typevec_size == 0)
2278 work -> typevec_size = 3;
2279 work -> typevec =
2280 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2282 else
2284 work -> typevec_size *= 2;
2285 work -> typevec =
2286 (char **) xrealloc ((char *)work -> typevec,
2287 sizeof (char *) * work -> typevec_size);
2290 tem = xmalloc (len + 1);
2291 memcpy (tem, start, len);
2292 tem[len] = '\0';
2293 work -> typevec[work -> ntypes++] = tem;
2296 /* Forget the remembered types, but not the type vector itself. */
2298 static void
2299 forget_types (work)
2300 struct work_stuff *work;
2302 int i;
2304 while (work -> ntypes > 0)
2306 i = --(work -> ntypes);
2307 if (work -> typevec[i] != NULL)
2309 free (work -> typevec[i]);
2310 work -> typevec[i] = NULL;
2315 /* Process the argument list part of the signature, after any class spec
2316 has been consumed, as well as the first 'F' character (if any). For
2317 example:
2319 "__als__3fooRT0" => process "RT0"
2320 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2322 DECLP must be already initialised, usually non-empty. It won't be freed
2323 on failure.
2325 Note that g++ differs significantly from ARM and lucid style mangling
2326 with regards to references to previously seen types. For example, given
2327 the source fragment:
2329 class foo {
2330 public:
2331 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2334 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2335 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2337 g++ produces the names:
2339 __3fooiRT0iT2iT2
2340 foo__FiR3fooiT1iT1
2342 while lcc (and presumably other ARM style compilers as well) produces:
2344 foo__FiR3fooT1T2T1T2
2345 __ct__3fooFiR3fooT1T2T1T2
2347 Note that g++ bases it's type numbers starting at zero and counts all
2348 previously seen types, while lucid/ARM bases it's type numbers starting
2349 at one and only considers types after it has seen the 'F' character
2350 indicating the start of the function args. For lucid/ARM style, we
2351 account for this difference by discarding any previously seen types when
2352 we see the 'F' character, and subtracting one from the type number
2353 reference.
2357 static int
2358 demangle_args (work, mangled, declp)
2359 struct work_stuff *work;
2360 const char **mangled;
2361 string *declp;
2363 string arg;
2364 int need_comma = 0;
2365 int r;
2366 int t;
2367 const char *tem;
2368 char temptype;
2370 if (PRINT_ARG_TYPES)
2372 string_append (declp, "(");
2373 if (**mangled == '\0')
2375 string_append (declp, "void");
2379 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2381 if ((**mangled == 'N') || (**mangled == 'T'))
2383 temptype = *(*mangled)++;
2385 if (temptype == 'N')
2387 if (!get_count (mangled, &r))
2389 return (0);
2392 else
2394 r = 1;
2396 if (ARM_DEMANGLING && work -> ntypes >= 10)
2398 /* If we have 10 or more types we might have more than a 1 digit
2399 index so we'll have to consume the whole count here. This
2400 will loose if the next thing is a type name preceeded by a
2401 count but it's impossible to demangle that case properly
2402 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2403 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2404 Pc, ...)" or "(..., type12, char *, ...)" */
2405 if ((t = consume_count(mangled)) == 0)
2407 return (0);
2410 else
2412 if (!get_count (mangled, &t))
2414 return (0);
2417 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2419 t--;
2421 /* Validate the type index. Protect against illegal indices from
2422 malformed type strings. */
2423 if ((t < 0) || (t >= work -> ntypes))
2425 return (0);
2427 while (--r >= 0)
2429 tem = work -> typevec[t];
2430 if (need_comma && PRINT_ARG_TYPES)
2432 string_append (declp, ", ");
2434 if (!do_arg (work, &tem, &arg))
2436 return (0);
2438 if (PRINT_ARG_TYPES)
2440 string_appends (declp, &arg);
2442 string_delete (&arg);
2443 need_comma = 1;
2446 else
2448 if (need_comma & PRINT_ARG_TYPES)
2450 string_append (declp, ", ");
2452 if (!do_arg (work, mangled, &arg))
2454 return (0);
2456 if (PRINT_ARG_TYPES)
2458 string_appends (declp, &arg);
2460 string_delete (&arg);
2461 need_comma = 1;
2465 if (**mangled == 'e')
2467 (*mangled)++;
2468 if (PRINT_ARG_TYPES)
2470 if (need_comma)
2472 string_append (declp, ",");
2474 string_append (declp, "...");
2478 if (PRINT_ARG_TYPES)
2480 string_append (declp, ")");
2482 return (1);
2485 static void
2486 demangle_function_name (work, mangled, declp, scan)
2487 struct work_stuff *work;
2488 const char **mangled;
2489 string *declp;
2490 const char *scan;
2492 int i;
2493 int len;
2494 string type;
2495 const char *tem;
2497 string_appendn (declp, (*mangled), scan - (*mangled));
2498 string_need (declp, 1);
2499 *(declp -> p) = '\0';
2501 /* Consume the function name, including the "__" separating the name
2502 from the signature. We are guaranteed that SCAN points to the
2503 separator. */
2505 (*mangled) = scan + 2;
2507 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2510 /* See if we have an ARM style constructor or destructor operator.
2511 If so, then just record it, clear the decl, and return.
2512 We can't build the actual constructor/destructor decl until later,
2513 when we recover the class name from the signature. */
2515 if (strcmp (declp -> b, "__ct") == 0)
2517 work -> constructor += 1;
2518 string_clear (declp);
2519 return;
2521 else if (strcmp (declp -> b, "__dt") == 0)
2523 work -> destructor += 1;
2524 string_clear (declp);
2525 return;
2529 if (declp->p - declp->b >= 3
2530 && declp->b[0] == 'o'
2531 && declp->b[1] == 'p'
2532 && strchr (cplus_markers, declp->b[2]) != NULL)
2534 /* see if it's an assignment expression */
2535 if (declp->p - declp->b >= 10 /* op$assign_ */
2536 && memcmp (declp->b + 3, "assign_", 7) == 0)
2538 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2540 len = declp->p - declp->b - 10;
2541 if (strlen (optable[i].in) == len
2542 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2544 string_clear (declp);
2545 string_append (declp, "operator");
2546 string_append (declp, optable[i].out);
2547 string_append (declp, "=");
2548 break;
2552 else
2554 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2556 int len = declp->p - declp->b - 3;
2557 if (strlen (optable[i].in) == len
2558 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2560 string_clear (declp);
2561 string_append (declp, "operator");
2562 string_append (declp, optable[i].out);
2563 break;
2568 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2569 && strchr (cplus_markers, declp->b[4]) != NULL)
2571 /* type conversion operator */
2572 tem = declp->b + 5;
2573 if (do_type (work, &tem, &type))
2575 string_clear (declp);
2576 string_append (declp, "operator ");
2577 string_appends (declp, &type);
2578 string_delete (&type);
2581 else if (declp->b[0] == '_' && declp->b[1] == '_'
2582 && declp->b[2] == 'o' && declp->b[3] == 'p')
2584 /* ANSI. */
2585 /* type conversion operator. */
2586 tem = declp->b + 4;
2587 if (do_type (work, &tem, &type))
2589 string_clear (declp);
2590 string_append (declp, "operator ");
2591 string_appends (declp, &type);
2592 string_delete (&type);
2595 else if (declp->b[0] == '_' && declp->b[1] == '_'
2596 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2597 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2599 if (declp->b[4] == '\0')
2601 /* Operator. */
2602 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2604 if (strlen (optable[i].in) == 2
2605 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2607 string_clear (declp);
2608 string_append (declp, "operator");
2609 string_append (declp, optable[i].out);
2610 break;
2614 else
2616 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2618 /* Assignment. */
2619 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2621 if (strlen (optable[i].in) == 3
2622 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2624 string_clear (declp);
2625 string_append (declp, "operator");
2626 string_append (declp, optable[i].out);
2627 break;
2635 /* a mini string-handling package */
2637 static void
2638 string_need (s, n)
2639 string *s;
2640 int n;
2642 int tem;
2644 if (s->b == NULL)
2646 if (n < 32)
2648 n = 32;
2650 s->p = s->b = xmalloc (n);
2651 s->e = s->b + n;
2653 else if (s->e - s->p < n)
2655 tem = s->p - s->b;
2656 n += tem;
2657 n *= 2;
2658 s->b = xrealloc (s->b, n);
2659 s->p = s->b + tem;
2660 s->e = s->b + n;
2664 static void
2665 string_delete (s)
2666 string *s;
2668 if (s->b != NULL)
2670 free (s->b);
2671 s->b = s->e = s->p = NULL;
2675 static void
2676 string_init (s)
2677 string *s;
2679 s->b = s->p = s->e = NULL;
2682 static void
2683 string_clear (s)
2684 string *s;
2686 s->p = s->b;
2689 #if 0
2691 static int
2692 string_empty (s)
2693 string *s;
2695 return (s->b == s->p);
2698 #endif
2700 static void
2701 string_append (p, s)
2702 string *p;
2703 const char *s;
2705 int n;
2706 if (s == NULL || *s == '\0')
2707 return;
2708 n = strlen (s);
2709 string_need (p, n);
2710 memcpy (p->p, s, n);
2711 p->p += n;
2714 static void
2715 string_appends (p, s)
2716 string *p, *s;
2718 int n;
2720 if (s->b != s->p)
2722 n = s->p - s->b;
2723 string_need (p, n);
2724 memcpy (p->p, s->b, n);
2725 p->p += n;
2729 static void
2730 string_appendn (p, s, n)
2731 string *p;
2732 const char *s;
2733 int n;
2735 if (n != 0)
2737 string_need (p, n);
2738 memcpy (p->p, s, n);
2739 p->p += n;
2743 static void
2744 string_prepend (p, s)
2745 string *p;
2746 const char *s;
2748 if (s != NULL && *s != '\0')
2750 string_prependn (p, s, strlen (s));
2754 static void
2755 string_prepends (p, s)
2756 string *p, *s;
2758 if (s->b != s->p)
2760 string_prependn (p, s->b, s->p - s->b);
2764 static void
2765 string_prependn (p, s, n)
2766 string *p;
2767 const char *s;
2768 int n;
2770 char *q;
2772 if (n != 0)
2774 string_need (p, n);
2775 for (q = p->p - 1; q >= p->b; q--)
2777 q[n] = q[0];
2779 memcpy (p->b, s, n);
2780 p->p += n;
2784 /* To generate a standalone demangler program for testing purposes,
2785 just compile and link this file with -DMAIN and libiberty.a. When
2786 run, it demangles each command line arg, or each stdin string, and
2787 prints the result on stdout. */
2789 #ifdef MAIN
2791 static void
2792 demangle_it (mangled_name)
2793 char *mangled_name;
2795 char *result;
2797 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2798 if (result == NULL)
2800 printf ("%s\n", mangled_name);
2802 else
2804 printf ("%s\n", result);
2805 free (result);
2809 #include "getopt.h"
2811 static char *program_name;
2812 static char *program_version = VERSION;
2814 static void
2815 usage (stream, status)
2816 FILE *stream;
2817 int status;
2819 fprintf (stream, "\
2820 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2821 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2822 [--help] [--version] [arg...]\n",
2823 program_name);
2824 exit (status);
2827 #define MBUF_SIZE 512
2828 char mbuffer[MBUF_SIZE];
2830 /* Defined in the automatically-generated underscore.c. */
2831 extern int prepends_underscore;
2833 int strip_underscore = 0;
2835 static struct option long_options[] = {
2836 {"strip-underscores", no_argument, 0, '_'},
2837 {"format", required_argument, 0, 's'},
2838 {"help", no_argument, 0, 'h'},
2839 {"no-strip-underscores", no_argument, 0, 'n'},
2840 {"version", no_argument, 0, 'v'},
2841 {0, no_argument, 0, 0}
2845 main (argc, argv)
2846 int argc;
2847 char **argv;
2849 char *result;
2850 int c;
2852 program_name = argv[0];
2854 strip_underscore = prepends_underscore;
2856 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2858 switch (c)
2860 case '?':
2861 usage (stderr, 1);
2862 break;
2863 case 'h':
2864 usage (stdout, 0);
2865 case 'n':
2866 strip_underscore = 0;
2867 break;
2868 case 'v':
2869 printf ("GNU %s version %s\n", program_name, program_version);
2870 exit (0);
2871 case '_':
2872 strip_underscore = 1;
2873 break;
2874 case 's':
2875 if (strcmp (optarg, "gnu") == 0)
2877 current_demangling_style = gnu_demangling;
2879 else if (strcmp (optarg, "lucid") == 0)
2881 current_demangling_style = lucid_demangling;
2883 else if (strcmp (optarg, "arm") == 0)
2885 current_demangling_style = arm_demangling;
2887 else
2889 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2890 program_name, optarg);
2891 exit (1);
2893 break;
2897 if (optind < argc)
2899 for ( ; optind < argc; optind++)
2901 demangle_it (argv[optind]);
2904 else
2906 for (;;)
2908 int i = 0;
2909 c = getchar ();
2910 /* Try to read a label. */
2911 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2913 if (i >= MBUF_SIZE-1)
2914 break;
2915 mbuffer[i++] = c;
2916 c = getchar ();
2918 if (i > 0)
2920 int skip_first = 0;
2922 if (mbuffer[0] == '.')
2923 ++skip_first;
2924 if (strip_underscore && mbuffer[skip_first] == '_')
2925 ++skip_first;
2927 if (skip_first > i)
2928 skip_first = i;
2930 mbuffer[i] = 0;
2932 result = cplus_demangle (mbuffer + skip_first,
2933 DMGL_PARAMS | DMGL_ANSI);
2934 if (result)
2936 if (mbuffer[0] == '.')
2937 putc ('.', stdout);
2938 fputs (result, stdout);
2939 free (result);
2941 else
2942 fputs (mbuffer, stdout);
2944 fflush (stdout);
2946 if (c == EOF)
2947 break;
2948 putchar (c);
2952 exit (0);
2955 static void
2956 fatal (str)
2957 char *str;
2959 fprintf (stderr, "%s: %s\n", program_name, str);
2960 exit (1);
2963 char * malloc ();
2964 char * realloc ();
2966 char *
2967 xmalloc (size)
2968 unsigned size;
2970 register char *value = (char *) malloc (size);
2971 if (value == 0)
2972 fatal ("virtual memory exhausted");
2973 return value;
2976 char *
2977 xrealloc (ptr, size)
2978 char *ptr;
2979 unsigned size;
2981 register char *value = (char *) realloc (ptr, size);
2982 if (value == 0)
2983 fatal ("virtual memory exhausted");
2984 return value;
2986 #endif /* main */