2000-03-08 H.J. Lu (hjl@gnu.org)
[binutils.git] / libiberty / cplus-dem.c
blob52249d2b580c6d3809b1367ec51f15e089b81f86
1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 98, 1999 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
5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 Libiberty is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with libiberty; see the file COPYING.LIB. If
20 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
25 This file imports xmalloc and xrealloc, which are like malloc and
26 realloc except that they generate a fatal error if there is no
27 available memory. */
29 /* This file lives in both GCC and libiberty. When making changes, please
30 try not to break either. */
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
36 #include <ctype.h>
37 #include <sys/types.h>
38 #include <string.h>
39 #include <stdio.h>
41 #ifdef HAVE_STDLIB_H
42 #include <stdlib.h>
43 #else
44 char * malloc ();
45 char * realloc ();
46 #endif
48 #include <demangle.h>
49 #undef CURRENT_DEMANGLING_STYLE
50 #define CURRENT_DEMANGLING_STYLE work->options
52 #include "libiberty.h"
54 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
56 /* A value at least one greater than the maximum number of characters
57 that will be output when using the `%d' format with `printf'. */
58 #define INTBUF_SIZE 32
60 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
62 static const char *mystrstr PARAMS ((const char *, const char *));
64 static const char *
65 mystrstr (s1, s2)
66 const char *s1, *s2;
68 register const char *p = s1;
69 register int len = strlen (s2);
71 for (; (p = strchr (p, *s2)) != 0; p++)
73 if (strncmp (p, s2, len) == 0)
75 return (p);
78 return (0);
81 /* In order to allow a single demangler executable to demangle strings
82 using various common values of CPLUS_MARKER, as well as any specific
83 one set at compile time, we maintain a string containing all the
84 commonly used ones, and check to see if the marker we are looking for
85 is in that string. CPLUS_MARKER is usually '$' on systems where the
86 assembler can deal with that. Where the assembler can't, it's usually
87 '.' (but on many systems '.' is used for other things). We put the
88 current defined CPLUS_MARKER first (which defaults to '$'), followed
89 by the next most common value, followed by an explicit '$' in case
90 the value of CPLUS_MARKER is not '$'.
92 We could avoid this if we could just get g++ to tell us what the actual
93 cplus marker character is as part of the debug information, perhaps by
94 ensuring that it is the character that terminates the gcc<n>_compiled
95 marker symbol (FIXME). */
97 #if !defined (CPLUS_MARKER)
98 #define CPLUS_MARKER '$'
99 #endif
101 enum demangling_styles current_demangling_style = gnu_demangling;
103 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
105 static char char_str[2] = { '\000', '\000' };
107 void
108 set_cplus_marker_for_demangling (ch)
109 int ch;
111 cplus_markers[0] = ch;
114 typedef struct string /* Beware: these aren't required to be */
115 { /* '\0' terminated. */
116 char *b; /* pointer to start of string */
117 char *p; /* pointer after last character */
118 char *e; /* pointer after end of allocated space */
119 } string;
121 /* Stuff that is shared between sub-routines.
122 Using a shared structure allows cplus_demangle to be reentrant. */
124 struct work_stuff
126 int options;
127 char **typevec;
128 char **ktypevec;
129 char **btypevec;
130 int numk;
131 int numb;
132 int ksize;
133 int bsize;
134 int ntypes;
135 int typevec_size;
136 int constructor;
137 int destructor;
138 int static_type; /* A static member function */
139 int temp_start; /* index in demangled to start of template args */
140 int type_quals; /* The type qualifiers. */
141 int dllimported; /* Symbol imported from a PE DLL */
142 char **tmpl_argvec; /* Template function arguments. */
143 int ntmpl_args; /* The number of template function arguments. */
144 int forgetting_types; /* Nonzero if we are not remembering the types
145 we see. */
146 string* previous_argument; /* The last function argument demangled. */
147 int nrepeats; /* The number of times to repeat the previous
148 argument. */
151 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
152 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
154 static const struct optable
156 const char *in;
157 const char *out;
158 int flags;
159 } optable[] = {
160 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
161 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
162 {"new", " new", 0}, /* old (1.91, and 1.x) */
163 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
164 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
165 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
166 {"as", "=", DMGL_ANSI}, /* ansi */
167 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
168 {"eq", "==", DMGL_ANSI}, /* old, ansi */
169 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
170 {"gt", ">", DMGL_ANSI}, /* old, ansi */
171 {"le", "<=", DMGL_ANSI}, /* old, ansi */
172 {"lt", "<", DMGL_ANSI}, /* old, ansi */
173 {"plus", "+", 0}, /* old */
174 {"pl", "+", DMGL_ANSI}, /* ansi */
175 {"apl", "+=", DMGL_ANSI}, /* ansi */
176 {"minus", "-", 0}, /* old */
177 {"mi", "-", DMGL_ANSI}, /* ansi */
178 {"ami", "-=", DMGL_ANSI}, /* ansi */
179 {"mult", "*", 0}, /* old */
180 {"ml", "*", DMGL_ANSI}, /* ansi */
181 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
182 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
183 {"convert", "+", 0}, /* old (unary +) */
184 {"negate", "-", 0}, /* old (unary -) */
185 {"trunc_mod", "%", 0}, /* old */
186 {"md", "%", DMGL_ANSI}, /* ansi */
187 {"amd", "%=", DMGL_ANSI}, /* ansi */
188 {"trunc_div", "/", 0}, /* old */
189 {"dv", "/", DMGL_ANSI}, /* ansi */
190 {"adv", "/=", DMGL_ANSI}, /* ansi */
191 {"truth_andif", "&&", 0}, /* old */
192 {"aa", "&&", DMGL_ANSI}, /* ansi */
193 {"truth_orif", "||", 0}, /* old */
194 {"oo", "||", DMGL_ANSI}, /* ansi */
195 {"truth_not", "!", 0}, /* old */
196 {"nt", "!", DMGL_ANSI}, /* ansi */
197 {"postincrement","++", 0}, /* old */
198 {"pp", "++", DMGL_ANSI}, /* ansi */
199 {"postdecrement","--", 0}, /* old */
200 {"mm", "--", DMGL_ANSI}, /* ansi */
201 {"bit_ior", "|", 0}, /* old */
202 {"or", "|", DMGL_ANSI}, /* ansi */
203 {"aor", "|=", DMGL_ANSI}, /* ansi */
204 {"bit_xor", "^", 0}, /* old */
205 {"er", "^", DMGL_ANSI}, /* ansi */
206 {"aer", "^=", DMGL_ANSI}, /* ansi */
207 {"bit_and", "&", 0}, /* old */
208 {"ad", "&", DMGL_ANSI}, /* ansi */
209 {"aad", "&=", DMGL_ANSI}, /* ansi */
210 {"bit_not", "~", 0}, /* old */
211 {"co", "~", DMGL_ANSI}, /* ansi */
212 {"call", "()", 0}, /* old */
213 {"cl", "()", DMGL_ANSI}, /* ansi */
214 {"alshift", "<<", 0}, /* old */
215 {"ls", "<<", DMGL_ANSI}, /* ansi */
216 {"als", "<<=", DMGL_ANSI}, /* ansi */
217 {"arshift", ">>", 0}, /* old */
218 {"rs", ">>", DMGL_ANSI}, /* ansi */
219 {"ars", ">>=", DMGL_ANSI}, /* ansi */
220 {"component", "->", 0}, /* old */
221 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
222 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
223 {"indirect", "*", 0}, /* old */
224 {"method_call", "->()", 0}, /* old */
225 {"addr", "&", 0}, /* old (unary &) */
226 {"array", "[]", 0}, /* old */
227 {"vc", "[]", DMGL_ANSI}, /* ansi */
228 {"compound", ", ", 0}, /* old */
229 {"cm", ", ", DMGL_ANSI}, /* ansi */
230 {"cond", "?:", 0}, /* old */
231 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
232 {"max", ">?", 0}, /* old */
233 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
234 {"min", "<?", 0}, /* old */
235 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
236 {"nop", "", 0}, /* old (for operator=) */
237 {"rm", "->*", DMGL_ANSI}, /* ansi */
238 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
241 /* These values are used to indicate the various type varieties.
242 They are all non-zero so that they can be used as `success'
243 values. */
244 typedef enum type_kind_t
246 tk_none,
247 tk_pointer,
248 tk_reference,
249 tk_integral,
250 tk_bool,
251 tk_char,
252 tk_real
253 } type_kind_t;
255 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
256 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
257 string_prepend(str, " ");}
258 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
259 string_append(str, " ");}
260 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
262 /* The scope separator appropriate for the language being demangled. */
264 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
266 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
267 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
269 /* Prototypes for local functions */
271 static char *
272 mop_up PARAMS ((struct work_stuff *, string *, int));
274 static void
275 squangle_mop_up PARAMS ((struct work_stuff *));
277 #if 0
278 static int
279 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
280 #endif
282 static char *
283 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
285 static int
286 demangle_template_template_parm PARAMS ((struct work_stuff *work,
287 const char **, string *));
289 static int
290 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
291 string *, int, int));
293 static int
294 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
295 const char **));
297 static int
298 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
300 static int
301 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
302 int, int));
304 static int
305 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
307 static int
308 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
310 static int
311 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
313 static int
314 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
316 static int
317 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
319 static int
320 arm_special PARAMS ((const char **, string *));
322 static void
323 string_need PARAMS ((string *, int));
325 static void
326 string_delete PARAMS ((string *));
328 static void
329 string_init PARAMS ((string *));
331 static void
332 string_clear PARAMS ((string *));
334 #if 0
335 static int
336 string_empty PARAMS ((string *));
337 #endif
339 static void
340 string_append PARAMS ((string *, const char *));
342 static void
343 string_appends PARAMS ((string *, string *));
345 static void
346 string_appendn PARAMS ((string *, const char *, int));
348 static void
349 string_prepend PARAMS ((string *, const char *));
351 static void
352 string_prependn PARAMS ((string *, const char *, int));
354 static void
355 string_append_template_idx PARAMS ((string *, int));
357 static int
358 get_count PARAMS ((const char **, int *));
360 static int
361 consume_count PARAMS ((const char **));
363 static int
364 consume_count_with_underscores PARAMS ((const char**));
366 static int
367 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
369 static int
370 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
372 static int
373 do_type PARAMS ((struct work_stuff *, const char **, string *));
375 static int
376 do_arg PARAMS ((struct work_stuff *, const char **, string *));
378 static void
379 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
380 const char *));
382 static void
383 remember_type PARAMS ((struct work_stuff *, const char *, int));
385 static void
386 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
388 static int
389 register_Btype PARAMS ((struct work_stuff *));
391 static void
392 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
394 static void
395 forget_types PARAMS ((struct work_stuff *));
397 static void
398 forget_B_and_K_types PARAMS ((struct work_stuff *));
400 static void
401 string_prepends PARAMS ((string *, string *));
403 static int
404 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
405 string*, type_kind_t));
407 static int
408 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
410 static int
411 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
413 static int
414 snarf_numeric_literal PARAMS ((const char **, string *));
416 /* There is a TYPE_QUAL value for each type qualifier. They can be
417 combined by bitwise-or to form the complete set of qualifiers for a
418 type. */
420 #define TYPE_UNQUALIFIED 0x0
421 #define TYPE_QUAL_CONST 0x1
422 #define TYPE_QUAL_VOLATILE 0x2
423 #define TYPE_QUAL_RESTRICT 0x4
425 static int
426 code_for_qualifier PARAMS ((int));
428 static const char*
429 qualifier_string PARAMS ((int));
431 static const char*
432 demangle_qualifier PARAMS ((int));
434 static int
435 demangle_expression PARAMS ((struct work_stuff *, const char **, string *,
436 type_kind_t));
438 static int
439 demangle_integral_value PARAMS ((struct work_stuff *, const char **,
440 string *));
442 static int
443 demangle_real_value PARAMS ((struct work_stuff *, const char **, string *));
445 static void
446 demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
447 string *));
449 static void
450 recursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
451 int));
453 /* Translate count to integer, consuming tokens in the process.
454 Conversion terminates on the first non-digit character.
456 Trying to consume something that isn't a count results in no
457 consumption of input and a return of -1.
459 Overflow consumes the rest of the digits, and returns -1. */
461 static int
462 consume_count (type)
463 const char **type;
465 int count = 0;
467 if (! isdigit ((unsigned char)**type))
468 return -1;
470 while (isdigit ((unsigned char)**type))
472 count *= 10;
474 /* Check for overflow.
475 We assume that count is represented using two's-complement;
476 no power of two is divisible by ten, so if an overflow occurs
477 when multiplying by ten, the result will not be a multiple of
478 ten. */
479 if ((count % 10) != 0)
481 while (isdigit ((unsigned char) **type))
482 (*type)++;
483 return -1;
486 count += **type - '0';
487 (*type)++;
490 return (count);
494 /* Like consume_count, but for counts that are preceded and followed
495 by '_' if they are greater than 10. Also, -1 is returned for
496 failure, since 0 can be a valid value. */
498 static int
499 consume_count_with_underscores (mangled)
500 const char **mangled;
502 int idx;
504 if (**mangled == '_')
506 (*mangled)++;
507 if (!isdigit ((unsigned char)**mangled))
508 return -1;
510 idx = consume_count (mangled);
511 if (**mangled != '_')
512 /* The trailing underscore was missing. */
513 return -1;
515 (*mangled)++;
517 else
519 if (**mangled < '0' || **mangled > '9')
520 return -1;
522 idx = **mangled - '0';
523 (*mangled)++;
526 return idx;
529 /* C is the code for a type-qualifier. Return the TYPE_QUAL
530 corresponding to this qualifier. */
532 static int
533 code_for_qualifier (c)
534 int c;
536 switch (c)
538 case 'C':
539 return TYPE_QUAL_CONST;
541 case 'V':
542 return TYPE_QUAL_VOLATILE;
544 case 'u':
545 return TYPE_QUAL_RESTRICT;
547 default:
548 break;
551 /* C was an invalid qualifier. */
552 abort ();
555 /* Return the string corresponding to the qualifiers given by
556 TYPE_QUALS. */
558 static const char*
559 qualifier_string (type_quals)
560 int type_quals;
562 switch (type_quals)
564 case TYPE_UNQUALIFIED:
565 return "";
567 case TYPE_QUAL_CONST:
568 return "const";
570 case TYPE_QUAL_VOLATILE:
571 return "volatile";
573 case TYPE_QUAL_RESTRICT:
574 return "__restrict";
576 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
577 return "const volatile";
579 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
580 return "const __restrict";
582 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
583 return "volatile __restrict";
585 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
586 return "const volatile __restrict";
588 default:
589 break;
592 /* TYPE_QUALS was an invalid qualifier set. */
593 abort ();
596 /* C is the code for a type-qualifier. Return the string
597 corresponding to this qualifier. This function should only be
598 called with a valid qualifier code. */
600 static const char*
601 demangle_qualifier (c)
602 int c;
604 return qualifier_string (code_for_qualifier (c));
608 cplus_demangle_opname (opname, result, options)
609 const char *opname;
610 char *result;
611 int options;
613 int len, len1, ret;
614 string type;
615 struct work_stuff work[1];
616 const char *tem;
618 len = strlen(opname);
619 result[0] = '\0';
620 ret = 0;
621 memset ((char *) work, 0, sizeof (work));
622 work->options = options;
624 if (opname[0] == '_' && opname[1] == '_'
625 && opname[2] == 'o' && opname[3] == 'p')
627 /* ANSI. */
628 /* type conversion operator. */
629 tem = opname + 4;
630 if (do_type (work, &tem, &type))
632 strcat (result, "operator ");
633 strncat (result, type.b, type.p - type.b);
634 string_delete (&type);
635 ret = 1;
638 else if (opname[0] == '_' && opname[1] == '_'
639 && opname[2] >= 'a' && opname[2] <= 'z'
640 && opname[3] >= 'a' && opname[3] <= 'z')
642 if (opname[4] == '\0')
644 /* Operator. */
645 size_t i;
646 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
648 if (strlen (optable[i].in) == 2
649 && memcmp (optable[i].in, opname + 2, 2) == 0)
651 strcat (result, "operator");
652 strcat (result, optable[i].out);
653 ret = 1;
654 break;
658 else
660 if (opname[2] == 'a' && opname[5] == '\0')
662 /* Assignment. */
663 size_t i;
664 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
666 if (strlen (optable[i].in) == 3
667 && memcmp (optable[i].in, opname + 2, 3) == 0)
669 strcat (result, "operator");
670 strcat (result, optable[i].out);
671 ret = 1;
672 break;
678 else if (len >= 3
679 && opname[0] == 'o'
680 && opname[1] == 'p'
681 && strchr (cplus_markers, opname[2]) != NULL)
683 /* see if it's an assignment expression */
684 if (len >= 10 /* op$assign_ */
685 && memcmp (opname + 3, "assign_", 7) == 0)
687 size_t i;
688 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
690 len1 = len - 10;
691 if ((int) strlen (optable[i].in) == len1
692 && memcmp (optable[i].in, opname + 10, len1) == 0)
694 strcat (result, "operator");
695 strcat (result, optable[i].out);
696 strcat (result, "=");
697 ret = 1;
698 break;
702 else
704 size_t i;
705 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
707 len1 = len - 3;
708 if ((int) strlen (optable[i].in) == len1
709 && memcmp (optable[i].in, opname + 3, len1) == 0)
711 strcat (result, "operator");
712 strcat (result, optable[i].out);
713 ret = 1;
714 break;
719 else if (len >= 5 && memcmp (opname, "type", 4) == 0
720 && strchr (cplus_markers, opname[4]) != NULL)
722 /* type conversion operator */
723 tem = opname + 5;
724 if (do_type (work, &tem, &type))
726 strcat (result, "operator ");
727 strncat (result, type.b, type.p - type.b);
728 string_delete (&type);
729 ret = 1;
732 squangle_mop_up (work);
733 return ret;
736 /* Takes operator name as e.g. "++" and returns mangled
737 operator name (e.g. "postincrement_expr"), or NULL if not found.
739 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
740 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
742 const char *
743 cplus_mangle_opname (opname, options)
744 const char *opname;
745 int options;
747 size_t i;
748 int len;
750 len = strlen (opname);
751 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
753 if ((int) strlen (optable[i].out) == len
754 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
755 && memcmp (optable[i].out, opname, len) == 0)
756 return optable[i].in;
758 return (0);
761 /* char *cplus_demangle (const char *mangled, int options)
763 If MANGLED is a mangled function name produced by GNU C++, then
764 a pointer to a malloced string giving a C++ representation
765 of the name will be returned; otherwise NULL will be returned.
766 It is the caller's responsibility to free the string which
767 is returned.
769 The OPTIONS arg may contain one or more of the following bits:
771 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
772 included.
773 DMGL_PARAMS Function parameters are included.
775 For example,
777 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
778 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
779 cplus_demangle ("foo__1Ai", 0) => "A::foo"
781 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
782 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
783 cplus_demangle ("foo__1Afe", 0) => "A::foo"
785 Note that any leading underscores, or other such characters prepended by
786 the compilation system, are presumed to have already been stripped from
787 MANGLED. */
789 char *
790 cplus_demangle (mangled, options)
791 const char *mangled;
792 int options;
794 char *ret;
795 struct work_stuff work[1];
796 memset ((char *) work, 0, sizeof (work));
797 work -> options = options;
798 if ((work -> options & DMGL_STYLE_MASK) == 0)
799 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
801 ret = internal_cplus_demangle (work, mangled);
802 squangle_mop_up (work);
803 return (ret);
807 /* This function performs most of what cplus_demangle use to do, but
808 to be able to demangle a name with a B, K or n code, we need to
809 have a longer term memory of what types have been seen. The original
810 now intializes and cleans up the squangle code info, while internal
811 calls go directly to this routine to avoid resetting that info. */
813 static char *
814 internal_cplus_demangle (work, mangled)
815 struct work_stuff *work;
816 const char *mangled;
819 string decl;
820 int success = 0;
821 char *demangled = NULL;
822 int s1,s2,s3,s4;
823 s1 = work->constructor;
824 s2 = work->destructor;
825 s3 = work->static_type;
826 s4 = work->type_quals;
827 work->constructor = work->destructor = 0;
828 work->type_quals = TYPE_UNQUALIFIED;
829 work->dllimported = 0;
831 if ((mangled != NULL) && (*mangled != '\0'))
833 string_init (&decl);
835 /* First check to see if gnu style demangling is active and if the
836 string to be demangled contains a CPLUS_MARKER. If so, attempt to
837 recognize one of the gnu special forms rather than looking for a
838 standard prefix. In particular, don't worry about whether there
839 is a "__" string in the mangled string. Consider "_$_5__foo" for
840 example. */
842 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
844 success = gnu_special (work, &mangled, &decl);
846 if (!success)
848 success = demangle_prefix (work, &mangled, &decl);
850 if (success && (*mangled != '\0'))
852 success = demangle_signature (work, &mangled, &decl);
854 if (work->constructor == 2)
856 string_prepend (&decl, "global constructors keyed to ");
857 work->constructor = 0;
859 else if (work->destructor == 2)
861 string_prepend (&decl, "global destructors keyed to ");
862 work->destructor = 0;
864 else if (work->dllimported == 1)
866 string_prepend (&decl, "import stub for ");
867 work->dllimported = 0;
869 demangled = mop_up (work, &decl, success);
871 work->constructor = s1;
872 work->destructor = s2;
873 work->static_type = s3;
874 work->type_quals = s4;
875 return (demangled);
879 /* Clear out and squangling related storage */
880 static void
881 squangle_mop_up (work)
882 struct work_stuff *work;
884 /* clean up the B and K type mangling types. */
885 forget_B_and_K_types (work);
886 if (work -> btypevec != NULL)
888 free ((char *) work -> btypevec);
890 if (work -> ktypevec != NULL)
892 free ((char *) work -> ktypevec);
896 /* Clear out any mangled storage */
898 static char *
899 mop_up (work, declp, success)
900 struct work_stuff *work;
901 string *declp;
902 int success;
904 char *demangled = NULL;
906 /* Discard the remembered types, if any. */
908 forget_types (work);
909 if (work -> typevec != NULL)
911 free ((char *) work -> typevec);
912 work -> typevec = NULL;
913 work -> typevec_size = 0;
915 if (work->tmpl_argvec)
917 int i;
919 for (i = 0; i < work->ntmpl_args; i++)
920 if (work->tmpl_argvec[i])
921 free ((char*) work->tmpl_argvec[i]);
923 free ((char*) work->tmpl_argvec);
924 work->tmpl_argvec = NULL;
926 if (work->previous_argument)
928 string_delete (work->previous_argument);
929 free ((char*) work->previous_argument);
930 work->previous_argument = NULL;
933 /* If demangling was successful, ensure that the demangled string is null
934 terminated and return it. Otherwise, free the demangling decl. */
936 if (!success)
938 string_delete (declp);
940 else
942 string_appendn (declp, "", 1);
943 demangled = declp -> b;
945 return (demangled);
950 LOCAL FUNCTION
952 demangle_signature -- demangle the signature part of a mangled name
954 SYNOPSIS
956 static int
957 demangle_signature (struct work_stuff *work, const char **mangled,
958 string *declp);
960 DESCRIPTION
962 Consume and demangle the signature portion of the mangled name.
964 DECLP is the string where demangled output is being built. At
965 entry it contains the demangled root name from the mangled name
966 prefix. I.E. either a demangled operator name or the root function
967 name. In some special cases, it may contain nothing.
969 *MANGLED points to the current unconsumed location in the mangled
970 name. As tokens are consumed and demangling is performed, the
971 pointer is updated to continuously point at the next token to
972 be consumed.
974 Demangling GNU style mangled names is nasty because there is no
975 explicit token that marks the start of the outermost function
976 argument list. */
978 static int
979 demangle_signature (work, mangled, declp)
980 struct work_stuff *work;
981 const char **mangled;
982 string *declp;
984 int success = 1;
985 int func_done = 0;
986 int expect_func = 0;
987 int expect_return_type = 0;
988 const char *oldmangled = NULL;
989 string trawname;
990 string tname;
992 while (success && (**mangled != '\0'))
994 switch (**mangled)
996 case 'Q':
997 oldmangled = *mangled;
998 success = demangle_qualified (work, mangled, declp, 1, 0);
999 if (success)
1000 remember_type (work, oldmangled, *mangled - oldmangled);
1001 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1002 expect_func = 1;
1003 oldmangled = NULL;
1004 break;
1006 case 'K':
1007 oldmangled = *mangled;
1008 success = demangle_qualified (work, mangled, declp, 1, 0);
1009 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1011 expect_func = 1;
1013 oldmangled = NULL;
1014 break;
1016 case 'S':
1017 /* Static member function */
1018 if (oldmangled == NULL)
1020 oldmangled = *mangled;
1022 (*mangled)++;
1023 work -> static_type = 1;
1024 break;
1026 case 'C':
1027 case 'V':
1028 case 'u':
1029 work->type_quals |= code_for_qualifier (**mangled);
1031 /* a qualified member function */
1032 if (oldmangled == NULL)
1033 oldmangled = *mangled;
1034 (*mangled)++;
1035 break;
1037 case 'L':
1038 /* Local class name follows after "Lnnn_" */
1039 if (HP_DEMANGLING)
1041 while (**mangled && (**mangled != '_'))
1042 (*mangled)++;
1043 if (!**mangled)
1044 success = 0;
1045 else
1046 (*mangled)++;
1048 else
1049 success = 0;
1050 break;
1052 case '0': case '1': case '2': case '3': case '4':
1053 case '5': case '6': case '7': case '8': case '9':
1054 if (oldmangled == NULL)
1056 oldmangled = *mangled;
1058 work->temp_start = -1; /* uppermost call to demangle_class */
1059 success = demangle_class (work, mangled, declp);
1060 if (success)
1062 remember_type (work, oldmangled, *mangled - oldmangled);
1064 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1066 /* EDG and others will have the "F", so we let the loop cycle
1067 if we are looking at one. */
1068 if (**mangled != 'F')
1069 expect_func = 1;
1071 oldmangled = NULL;
1072 break;
1074 case 'B':
1076 string s;
1077 success = do_type (work, mangled, &s);
1078 if (success)
1080 string_append (&s, SCOPE_STRING (work));
1081 string_prepends (declp, &s);
1083 oldmangled = NULL;
1084 expect_func = 1;
1086 break;
1088 case 'F':
1089 /* Function */
1090 /* ARM/HP style demangling includes a specific 'F' character after
1091 the class name. For GNU style, it is just implied. So we can
1092 safely just consume any 'F' at this point and be compatible
1093 with either style. */
1095 oldmangled = NULL;
1096 func_done = 1;
1097 (*mangled)++;
1099 /* For lucid/ARM/HP style we have to forget any types we might
1100 have remembered up to this point, since they were not argument
1101 types. GNU style considers all types seen as available for
1102 back references. See comment in demangle_args() */
1104 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1106 forget_types (work);
1108 success = demangle_args (work, mangled, declp);
1109 /* After picking off the function args, we expect to either
1110 find the function return type (preceded by an '_') or the
1111 end of the string. */
1112 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1114 ++(*mangled);
1115 /* At this level, we do not care about the return type. */
1116 success = do_type (work, mangled, &tname);
1117 string_delete (&tname);
1120 break;
1122 case 't':
1123 /* G++ Template */
1124 string_init(&trawname);
1125 string_init(&tname);
1126 if (oldmangled == NULL)
1128 oldmangled = *mangled;
1130 success = demangle_template (work, mangled, &tname,
1131 &trawname, 1, 1);
1132 if (success)
1134 remember_type (work, oldmangled, *mangled - oldmangled);
1136 string_append (&tname, SCOPE_STRING (work));
1138 string_prepends(declp, &tname);
1139 if (work -> destructor & 1)
1141 string_prepend (&trawname, "~");
1142 string_appends (declp, &trawname);
1143 work->destructor -= 1;
1145 if ((work->constructor & 1) || (work->destructor & 1))
1147 string_appends (declp, &trawname);
1148 work->constructor -= 1;
1150 string_delete(&trawname);
1151 string_delete(&tname);
1152 oldmangled = NULL;
1153 expect_func = 1;
1154 break;
1156 case '_':
1157 if (GNU_DEMANGLING && expect_return_type)
1159 /* Read the return type. */
1160 string return_type;
1161 string_init (&return_type);
1163 (*mangled)++;
1164 success = do_type (work, mangled, &return_type);
1165 APPEND_BLANK (&return_type);
1167 string_prepends (declp, &return_type);
1168 string_delete (&return_type);
1169 break;
1171 else
1172 /* At the outermost level, we cannot have a return type specified,
1173 so if we run into another '_' at this point we are dealing with
1174 a mangled name that is either bogus, or has been mangled by
1175 some algorithm we don't know how to deal with. So just
1176 reject the entire demangling. */
1177 /* However, "_nnn" is an expected suffix for alternate entry point
1178 numbered nnn for a function, with HP aCC, so skip over that
1179 without reporting failure. pai/1997-09-04 */
1180 if (HP_DEMANGLING)
1182 (*mangled)++;
1183 while (**mangled && isdigit ((unsigned char)**mangled))
1184 (*mangled)++;
1186 else
1187 success = 0;
1188 break;
1190 case 'H':
1191 if (GNU_DEMANGLING)
1193 /* A G++ template function. Read the template arguments. */
1194 success = demangle_template (work, mangled, declp, 0, 0,
1196 if (!(work->constructor & 1))
1197 expect_return_type = 1;
1198 (*mangled)++;
1199 break;
1201 else
1202 /* fall through */
1205 default:
1206 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1208 /* Assume we have stumbled onto the first outermost function
1209 argument token, and start processing args. */
1210 func_done = 1;
1211 success = demangle_args (work, mangled, declp);
1213 else
1215 /* Non-GNU demanglers use a specific token to mark the start
1216 of the outermost function argument tokens. Typically 'F',
1217 for ARM/HP-demangling, for example. So if we find something
1218 we are not prepared for, it must be an error. */
1219 success = 0;
1221 break;
1224 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1227 if (success && expect_func)
1229 func_done = 1;
1230 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1232 forget_types (work);
1234 success = demangle_args (work, mangled, declp);
1235 /* Since template include the mangling of their return types,
1236 we must set expect_func to 0 so that we don't try do
1237 demangle more arguments the next time we get here. */
1238 expect_func = 0;
1242 if (success && !func_done)
1244 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1246 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1247 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1248 first case, and need to ensure that the '(void)' gets added to
1249 the current declp. Note that with ARM/HP, the first case
1250 represents the name of a static data member 'foo::bar',
1251 which is in the current declp, so we leave it alone. */
1252 success = demangle_args (work, mangled, declp);
1255 if (success && PRINT_ARG_TYPES)
1257 if (work->static_type)
1258 string_append (declp, " static");
1259 if (work->type_quals != TYPE_UNQUALIFIED)
1261 APPEND_BLANK (declp);
1262 string_append (declp, qualifier_string (work->type_quals));
1266 return (success);
1269 #if 0
1271 static int
1272 demangle_method_args (work, mangled, declp)
1273 struct work_stuff *work;
1274 const char **mangled;
1275 string *declp;
1277 int success = 0;
1279 if (work -> static_type)
1281 string_append (declp, *mangled + 1);
1282 *mangled += strlen (*mangled);
1283 success = 1;
1285 else
1287 success = demangle_args (work, mangled, declp);
1289 return (success);
1292 #endif
1294 static int
1295 demangle_template_template_parm (work, mangled, tname)
1296 struct work_stuff *work;
1297 const char **mangled;
1298 string *tname;
1300 int i;
1301 int r;
1302 int need_comma = 0;
1303 int success = 1;
1304 string temp;
1306 string_append (tname, "template <");
1307 /* get size of template parameter list */
1308 if (get_count (mangled, &r))
1310 for (i = 0; i < r; i++)
1312 if (need_comma)
1314 string_append (tname, ", ");
1317 /* Z for type parameters */
1318 if (**mangled == 'Z')
1320 (*mangled)++;
1321 string_append (tname, "class");
1323 /* z for template parameters */
1324 else if (**mangled == 'z')
1326 (*mangled)++;
1327 success =
1328 demangle_template_template_parm (work, mangled, tname);
1329 if (!success)
1331 break;
1334 else
1336 /* temp is initialized in do_type */
1337 success = do_type (work, mangled, &temp);
1338 if (success)
1340 string_appends (tname, &temp);
1342 string_delete(&temp);
1343 if (!success)
1345 break;
1348 need_comma = 1;
1352 if (tname->p[-1] == '>')
1353 string_append (tname, " ");
1354 string_append (tname, "> class");
1355 return (success);
1358 static int
1359 demangle_expression (work, mangled, s, tk)
1360 struct work_stuff *work;
1361 const char** mangled;
1362 string* s;
1363 type_kind_t tk;
1365 int need_operator = 0;
1366 int success;
1368 success = 1;
1369 string_appendn (s, "(", 1);
1370 (*mangled)++;
1371 while (success && **mangled != 'W' && **mangled != '\0')
1373 if (need_operator)
1375 size_t i;
1376 size_t len;
1378 success = 0;
1380 len = strlen (*mangled);
1382 for (i = 0;
1383 i < sizeof (optable) / sizeof (optable [0]);
1384 ++i)
1386 size_t l = strlen (optable[i].in);
1388 if (l <= len
1389 && memcmp (optable[i].in, *mangled, l) == 0)
1391 string_appendn (s, " ", 1);
1392 string_append (s, optable[i].out);
1393 string_appendn (s, " ", 1);
1394 success = 1;
1395 (*mangled) += l;
1396 break;
1400 if (!success)
1401 break;
1403 else
1404 need_operator = 1;
1406 success = demangle_template_value_parm (work, mangled, s, tk);
1409 if (**mangled != 'W')
1410 success = 0;
1411 else
1413 string_appendn (s, ")", 1);
1414 (*mangled)++;
1417 return success;
1420 static int
1421 demangle_integral_value (work, mangled, s)
1422 struct work_stuff *work;
1423 const char** mangled;
1424 string* s;
1426 int success;
1428 if (**mangled == 'E')
1429 success = demangle_expression (work, mangled, s, tk_integral);
1430 else if (**mangled == 'Q' || **mangled == 'K')
1431 success = demangle_qualified (work, mangled, s, 0, 1);
1432 else
1434 int value;
1436 success = 0;
1438 /* Negative numbers are indicated with a leading `m'. */
1439 if (**mangled == 'm')
1441 string_appendn (s, "-", 1);
1442 (*mangled)++;
1445 /* Read the rest of the number. */
1446 value = consume_count_with_underscores (mangled);
1447 if (value != -1)
1449 char buf[INTBUF_SIZE];
1450 sprintf (buf, "%d", value);
1451 string_append (s, buf);
1453 /* If the next character is an underscore, skip it. */
1454 if (**mangled == '_')
1455 (*mangled)++;
1457 /* All is well. */
1458 success = 1;
1462 return success;
1465 /* Demangle the real value in MANGLED. */
1467 static int
1468 demangle_real_value (work, mangled, s)
1469 struct work_stuff *work;
1470 const char **mangled;
1471 string* s;
1473 if (**mangled == 'E')
1474 return demangle_expression (work, mangled, s, tk_real);
1476 if (**mangled == 'm')
1478 string_appendn (s, "-", 1);
1479 (*mangled)++;
1481 while (isdigit ((unsigned char)**mangled))
1483 string_appendn (s, *mangled, 1);
1484 (*mangled)++;
1486 if (**mangled == '.') /* fraction */
1488 string_appendn (s, ".", 1);
1489 (*mangled)++;
1490 while (isdigit ((unsigned char)**mangled))
1492 string_appendn (s, *mangled, 1);
1493 (*mangled)++;
1496 if (**mangled == 'e') /* exponent */
1498 string_appendn (s, "e", 1);
1499 (*mangled)++;
1500 while (isdigit ((unsigned char)**mangled))
1502 string_appendn (s, *mangled, 1);
1503 (*mangled)++;
1507 return 1;
1510 static int
1511 demangle_template_value_parm (work, mangled, s, tk)
1512 struct work_stuff *work;
1513 const char **mangled;
1514 string* s;
1515 type_kind_t tk;
1517 int success = 1;
1519 if (**mangled == 'Y')
1521 /* The next argument is a template parameter. */
1522 int idx;
1524 (*mangled)++;
1525 idx = consume_count_with_underscores (mangled);
1526 if (idx == -1
1527 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1528 || consume_count_with_underscores (mangled) == -1)
1529 return -1;
1530 if (work->tmpl_argvec)
1531 string_append (s, work->tmpl_argvec[idx]);
1532 else
1533 string_append_template_idx (s, idx);
1535 else if (tk == tk_integral)
1536 success = demangle_integral_value (work, mangled, s);
1537 else if (tk == tk_char)
1539 char tmp[2];
1540 int val;
1541 if (**mangled == 'm')
1543 string_appendn (s, "-", 1);
1544 (*mangled)++;
1546 string_appendn (s, "'", 1);
1547 val = consume_count(mangled);
1548 if (val <= 0)
1549 success = 0;
1550 else
1552 tmp[0] = (char)val;
1553 tmp[1] = '\0';
1554 string_appendn (s, &tmp[0], 1);
1555 string_appendn (s, "'", 1);
1558 else if (tk == tk_bool)
1560 int val = consume_count (mangled);
1561 if (val == 0)
1562 string_appendn (s, "false", 5);
1563 else if (val == 1)
1564 string_appendn (s, "true", 4);
1565 else
1566 success = 0;
1568 else if (tk == tk_real)
1569 success = demangle_real_value (work, mangled, s);
1570 else if (tk == tk_pointer || tk == tk_reference)
1572 if (**mangled == 'Q')
1573 success = demangle_qualified (work, mangled, s,
1574 /*isfuncname=*/0,
1575 /*append=*/1);
1576 else
1578 int symbol_len = consume_count (mangled);
1579 if (symbol_len == -1)
1580 return -1;
1581 if (symbol_len == 0)
1582 string_appendn (s, "0", 1);
1583 else
1585 char *p = xmalloc (symbol_len + 1), *q;
1586 strncpy (p, *mangled, symbol_len);
1587 p [symbol_len] = '\0';
1588 /* We use cplus_demangle here, rather than
1589 internal_cplus_demangle, because the name of the entity
1590 mangled here does not make use of any of the squangling
1591 or type-code information we have built up thus far; it is
1592 mangled independently. */
1593 q = cplus_demangle (p, work->options);
1594 if (tk == tk_pointer)
1595 string_appendn (s, "&", 1);
1596 /* FIXME: Pointer-to-member constants should get a
1597 qualifying class name here. */
1598 if (q)
1600 string_append (s, q);
1601 free (q);
1603 else
1604 string_append (s, p);
1605 free (p);
1607 *mangled += symbol_len;
1611 return success;
1614 /* Demangle the template name in MANGLED. The full name of the
1615 template (e.g., S<int>) is placed in TNAME. The name without the
1616 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1617 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1618 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1619 the tmeplate is remembered in the list of back-referenceable
1620 types. */
1622 static int
1623 demangle_template (work, mangled, tname, trawname, is_type, remember)
1624 struct work_stuff *work;
1625 const char **mangled;
1626 string *tname;
1627 string *trawname;
1628 int is_type;
1629 int remember;
1631 int i;
1632 int r;
1633 int need_comma = 0;
1634 int success = 0;
1635 const char *start;
1636 int is_java_array = 0;
1637 string temp;
1638 int bindex = 0;
1640 (*mangled)++;
1641 if (is_type)
1643 if (remember)
1644 bindex = register_Btype (work);
1645 start = *mangled;
1646 /* get template name */
1647 if (**mangled == 'z')
1649 int idx;
1650 (*mangled)++;
1651 (*mangled)++;
1653 idx = consume_count_with_underscores (mangled);
1654 if (idx == -1
1655 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1656 || consume_count_with_underscores (mangled) == -1)
1657 return (0);
1659 if (work->tmpl_argvec)
1661 string_append (tname, work->tmpl_argvec[idx]);
1662 if (trawname)
1663 string_append (trawname, work->tmpl_argvec[idx]);
1665 else
1667 string_append_template_idx (tname, idx);
1668 if (trawname)
1669 string_append_template_idx (trawname, idx);
1672 else
1674 if ((r = consume_count (mangled)) <= 0
1675 || (int) strlen (*mangled) < r)
1677 return (0);
1679 is_java_array = (work -> options & DMGL_JAVA)
1680 && strncmp (*mangled, "JArray1Z", 8) == 0;
1681 if (! is_java_array)
1683 string_appendn (tname, *mangled, r);
1685 if (trawname)
1686 string_appendn (trawname, *mangled, r);
1687 *mangled += r;
1690 if (!is_java_array)
1691 string_append (tname, "<");
1692 /* get size of template parameter list */
1693 if (!get_count (mangled, &r))
1695 return (0);
1697 if (!is_type)
1699 /* Create an array for saving the template argument values. */
1700 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1701 work->ntmpl_args = r;
1702 for (i = 0; i < r; i++)
1703 work->tmpl_argvec[i] = 0;
1705 for (i = 0; i < r; i++)
1707 if (need_comma)
1709 string_append (tname, ", ");
1711 /* Z for type parameters */
1712 if (**mangled == 'Z')
1714 (*mangled)++;
1715 /* temp is initialized in do_type */
1716 success = do_type (work, mangled, &temp);
1717 if (success)
1719 string_appends (tname, &temp);
1721 if (!is_type)
1723 /* Save the template argument. */
1724 int len = temp.p - temp.b;
1725 work->tmpl_argvec[i] = xmalloc (len + 1);
1726 memcpy (work->tmpl_argvec[i], temp.b, len);
1727 work->tmpl_argvec[i][len] = '\0';
1730 string_delete(&temp);
1731 if (!success)
1733 break;
1736 /* z for template parameters */
1737 else if (**mangled == 'z')
1739 int r2;
1740 (*mangled)++;
1741 success = demangle_template_template_parm (work, mangled, tname);
1743 if (success
1744 && (r2 = consume_count (mangled)) > 0
1745 && (int) strlen (*mangled) >= r2)
1747 string_append (tname, " ");
1748 string_appendn (tname, *mangled, r2);
1749 if (!is_type)
1751 /* Save the template argument. */
1752 int len = r2;
1753 work->tmpl_argvec[i] = xmalloc (len + 1);
1754 memcpy (work->tmpl_argvec[i], *mangled, len);
1755 work->tmpl_argvec[i][len] = '\0';
1757 *mangled += r2;
1759 if (!success)
1761 break;
1764 else
1766 string param;
1767 string* s;
1769 /* otherwise, value parameter */
1771 /* temp is initialized in do_type */
1772 success = do_type (work, mangled, &temp);
1773 string_delete(&temp);
1774 if (!success)
1775 break;
1777 if (!is_type)
1779 s = &param;
1780 string_init (s);
1782 else
1783 s = tname;
1785 success = demangle_template_value_parm (work, mangled, s,
1786 (type_kind_t) success);
1788 if (!success)
1790 if (!is_type)
1791 string_delete (s);
1792 success = 0;
1793 break;
1796 if (!is_type)
1798 int len = s->p - s->b;
1799 work->tmpl_argvec[i] = xmalloc (len + 1);
1800 memcpy (work->tmpl_argvec[i], s->b, len);
1801 work->tmpl_argvec[i][len] = '\0';
1803 string_appends (tname, s);
1804 string_delete (s);
1807 need_comma = 1;
1809 if (is_java_array)
1811 string_append (tname, "[]");
1813 else
1815 if (tname->p[-1] == '>')
1816 string_append (tname, " ");
1817 string_append (tname, ">");
1820 if (is_type && remember)
1821 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1824 if (work -> static_type)
1826 string_append (declp, *mangled + 1);
1827 *mangled += strlen (*mangled);
1828 success = 1;
1830 else
1832 success = demangle_args (work, mangled, declp);
1836 return (success);
1839 static int
1840 arm_pt (work, mangled, n, anchor, args)
1841 struct work_stuff *work;
1842 const char *mangled;
1843 int n;
1844 const char **anchor, **args;
1846 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1847 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1848 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1850 int len;
1851 *args = *anchor + 6;
1852 len = consume_count (args);
1853 if (len == -1)
1854 return 0;
1855 if (*args + len == mangled + n && **args == '_')
1857 ++*args;
1858 return 1;
1861 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1863 if ((*anchor = mystrstr (mangled, "__tm__"))
1864 || (*anchor = mystrstr (mangled, "__ps__"))
1865 || (*anchor = mystrstr (mangled, "__pt__")))
1867 int len;
1868 *args = *anchor + 6;
1869 len = consume_count (args);
1870 if (len == -1)
1871 return 0;
1872 if (*args + len == mangled + n && **args == '_')
1874 ++*args;
1875 return 1;
1878 else if ((*anchor = mystrstr (mangled, "__S")))
1880 int len;
1881 *args = *anchor + 3;
1882 len = consume_count (args);
1883 if (len == -1)
1884 return 0;
1885 if (*args + len == mangled + n && **args == '_')
1887 ++*args;
1888 return 1;
1893 return 0;
1896 static void
1897 demangle_arm_hp_template (work, mangled, n, declp)
1898 struct work_stuff *work;
1899 const char **mangled;
1900 int n;
1901 string *declp;
1903 const char *p;
1904 const char *args;
1905 const char *e = *mangled + n;
1906 string arg;
1908 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1909 template args */
1910 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1912 char *start_spec_args = NULL;
1914 /* First check for and omit template specialization pseudo-arguments,
1915 such as in "Spec<#1,#1.*>" */
1916 start_spec_args = strchr (*mangled, '<');
1917 if (start_spec_args && (start_spec_args - *mangled < n))
1918 string_appendn (declp, *mangled, start_spec_args - *mangled);
1919 else
1920 string_appendn (declp, *mangled, n);
1921 (*mangled) += n + 1;
1922 string_init (&arg);
1923 if (work->temp_start == -1) /* non-recursive call */
1924 work->temp_start = declp->p - declp->b;
1925 string_append (declp, "<");
1926 while (1)
1928 string_clear (&arg);
1929 switch (**mangled)
1931 case 'T':
1932 /* 'T' signals a type parameter */
1933 (*mangled)++;
1934 if (!do_type (work, mangled, &arg))
1935 goto hpacc_template_args_done;
1936 break;
1938 case 'U':
1939 case 'S':
1940 /* 'U' or 'S' signals an integral value */
1941 if (!do_hpacc_template_const_value (work, mangled, &arg))
1942 goto hpacc_template_args_done;
1943 break;
1945 case 'A':
1946 /* 'A' signals a named constant expression (literal) */
1947 if (!do_hpacc_template_literal (work, mangled, &arg))
1948 goto hpacc_template_args_done;
1949 break;
1951 default:
1952 /* Today, 1997-09-03, we have only the above types
1953 of template parameters */
1954 /* FIXME: maybe this should fail and return null */
1955 goto hpacc_template_args_done;
1957 string_appends (declp, &arg);
1958 /* Check if we're at the end of template args.
1959 0 if at end of static member of template class,
1960 _ if done with template args for a function */
1961 if ((**mangled == '\000') || (**mangled == '_'))
1962 break;
1963 else
1964 string_append (declp, ",");
1966 hpacc_template_args_done:
1967 string_append (declp, ">");
1968 string_delete (&arg);
1969 if (**mangled == '_')
1970 (*mangled)++;
1971 return;
1973 /* ARM template? (Also handles HP cfront extensions) */
1974 else if (arm_pt (work, *mangled, n, &p, &args))
1976 string type_str;
1978 string_init (&arg);
1979 string_appendn (declp, *mangled, p - *mangled);
1980 if (work->temp_start == -1) /* non-recursive call */
1981 work->temp_start = declp->p - declp->b;
1982 string_append (declp, "<");
1983 /* should do error checking here */
1984 while (args < e) {
1985 string_clear (&arg);
1987 /* Check for type or literal here */
1988 switch (*args)
1990 /* HP cfront extensions to ARM for template args */
1991 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1992 /* FIXME: We handle only numeric literals for HP cfront */
1993 case 'X':
1994 /* A typed constant value follows */
1995 args++;
1996 if (!do_type (work, &args, &type_str))
1997 goto cfront_template_args_done;
1998 string_append (&arg, "(");
1999 string_appends (&arg, &type_str);
2000 string_append (&arg, ")");
2001 if (*args != 'L')
2002 goto cfront_template_args_done;
2003 args++;
2004 /* Now snarf a literal value following 'L' */
2005 if (!snarf_numeric_literal (&args, &arg))
2006 goto cfront_template_args_done;
2007 break;
2009 case 'L':
2010 /* Snarf a literal following 'L' */
2011 args++;
2012 if (!snarf_numeric_literal (&args, &arg))
2013 goto cfront_template_args_done;
2014 break;
2015 default:
2016 /* Not handling other HP cfront stuff */
2017 if (!do_type (work, &args, &arg))
2018 goto cfront_template_args_done;
2020 string_appends (declp, &arg);
2021 string_append (declp, ",");
2023 cfront_template_args_done:
2024 string_delete (&arg);
2025 if (args >= e)
2026 --declp->p; /* remove extra comma */
2027 string_append (declp, ">");
2029 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2030 && (*mangled)[9] == 'N'
2031 && (*mangled)[8] == (*mangled)[10]
2032 && strchr (cplus_markers, (*mangled)[8]))
2034 /* A member of the anonymous namespace. */
2035 string_append (declp, "{anonymous}");
2037 else
2039 if (work->temp_start == -1) /* non-recursive call only */
2040 work->temp_start = 0; /* disable in recursive calls */
2041 string_appendn (declp, *mangled, n);
2043 *mangled += n;
2046 /* Extract a class name, possibly a template with arguments, from the
2047 mangled string; qualifiers, local class indicators, etc. have
2048 already been dealt with */
2050 static int
2051 demangle_class_name (work, mangled, declp)
2052 struct work_stuff *work;
2053 const char **mangled;
2054 string *declp;
2056 int n;
2057 int success = 0;
2059 n = consume_count (mangled);
2060 if (n == -1)
2061 return 0;
2062 if ((int) strlen (*mangled) >= n)
2064 demangle_arm_hp_template (work, mangled, n, declp);
2065 success = 1;
2068 return (success);
2073 LOCAL FUNCTION
2075 demangle_class -- demangle a mangled class sequence
2077 SYNOPSIS
2079 static int
2080 demangle_class (struct work_stuff *work, const char **mangled,
2081 strint *declp)
2083 DESCRIPTION
2085 DECLP points to the buffer into which demangling is being done.
2087 *MANGLED points to the current token to be demangled. On input,
2088 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2089 On exit, it points to the next token after the mangled class on
2090 success, or the first unconsumed token on failure.
2092 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2093 we are demangling a constructor or destructor. In this case
2094 we prepend "class::class" or "class::~class" to DECLP.
2096 Otherwise, we prepend "class::" to the current DECLP.
2098 Reset the constructor/destructor flags once they have been
2099 "consumed". This allows demangle_class to be called later during
2100 the same demangling, to do normal class demangling.
2102 Returns 1 if demangling is successful, 0 otherwise.
2106 static int
2107 demangle_class (work, mangled, declp)
2108 struct work_stuff *work;
2109 const char **mangled;
2110 string *declp;
2112 int success = 0;
2113 int btype;
2114 string class_name;
2115 char *save_class_name_end = 0;
2117 string_init (&class_name);
2118 btype = register_Btype (work);
2119 if (demangle_class_name (work, mangled, &class_name))
2121 save_class_name_end = class_name.p;
2122 if ((work->constructor & 1) || (work->destructor & 1))
2124 /* adjust so we don't include template args */
2125 if (work->temp_start && (work->temp_start != -1))
2127 class_name.p = class_name.b + work->temp_start;
2129 string_prepends (declp, &class_name);
2130 if (work -> destructor & 1)
2132 string_prepend (declp, "~");
2133 work -> destructor -= 1;
2135 else
2137 work -> constructor -= 1;
2140 class_name.p = save_class_name_end;
2141 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2142 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2143 string_prepend (declp, SCOPE_STRING (work));
2144 string_prepends (declp, &class_name);
2145 success = 1;
2147 string_delete (&class_name);
2148 return (success);
2153 LOCAL FUNCTION
2155 demangle_prefix -- consume the mangled name prefix and find signature
2157 SYNOPSIS
2159 static int
2160 demangle_prefix (struct work_stuff *work, const char **mangled,
2161 string *declp);
2163 DESCRIPTION
2165 Consume and demangle the prefix of the mangled name.
2167 DECLP points to the string buffer into which demangled output is
2168 placed. On entry, the buffer is empty. On exit it contains
2169 the root function name, the demangled operator name, or in some
2170 special cases either nothing or the completely demangled result.
2172 MANGLED points to the current pointer into the mangled name. As each
2173 token of the mangled name is consumed, it is updated. Upon entry
2174 the current mangled name pointer points to the first character of
2175 the mangled name. Upon exit, it should point to the first character
2176 of the signature if demangling was successful, or to the first
2177 unconsumed character if demangling of the prefix was unsuccessful.
2179 Returns 1 on success, 0 otherwise.
2182 static int
2183 demangle_prefix (work, mangled, declp)
2184 struct work_stuff *work;
2185 const char **mangled;
2186 string *declp;
2188 int success = 1;
2189 const char *scan;
2190 int i;
2192 if (strlen(*mangled) > 6
2193 && (strncmp(*mangled, "_imp__", 6) == 0
2194 || strncmp(*mangled, "__imp_", 6) == 0))
2196 /* it's a symbol imported from a PE dynamic library. Check for both
2197 new style prefix _imp__ and legacy __imp_ used by older versions
2198 of dlltool. */
2199 (*mangled) += 6;
2200 work->dllimported = 1;
2202 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2204 char *marker = strchr (cplus_markers, (*mangled)[8]);
2205 if (marker != NULL && *marker == (*mangled)[10])
2207 if ((*mangled)[9] == 'D')
2209 /* it's a GNU global destructor to be executed at program exit */
2210 (*mangled) += 11;
2211 work->destructor = 2;
2212 if (gnu_special (work, mangled, declp))
2213 return success;
2215 else if ((*mangled)[9] == 'I')
2217 /* it's a GNU global constructor to be executed at program init */
2218 (*mangled) += 11;
2219 work->constructor = 2;
2220 if (gnu_special (work, mangled, declp))
2221 return success;
2225 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2227 /* it's a ARM global destructor to be executed at program exit */
2228 (*mangled) += 7;
2229 work->destructor = 2;
2231 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2233 /* it's a ARM global constructor to be executed at program initial */
2234 (*mangled) += 7;
2235 work->constructor = 2;
2238 /* This block of code is a reduction in strength time optimization
2240 scan = mystrstr (*mangled, "__"); */
2243 scan = *mangled;
2245 do {
2246 scan = strchr (scan, '_');
2247 } while (scan != NULL && *++scan != '_');
2249 if (scan != NULL) --scan;
2252 if (scan != NULL)
2254 /* We found a sequence of two or more '_', ensure that we start at
2255 the last pair in the sequence. */
2256 i = strspn (scan, "_");
2257 if (i > 2)
2259 scan += (i - 2);
2263 if (scan == NULL)
2265 success = 0;
2267 else if (work -> static_type)
2269 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2271 success = 0;
2274 else if ((scan == *mangled)
2275 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2276 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2278 /* The ARM says nothing about the mangling of local variables.
2279 But cfront mangles local variables by prepending __<nesting_level>
2280 to them. As an extension to ARM demangling we handle this case. */
2281 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2282 && isdigit ((unsigned char)scan[2]))
2284 *mangled = scan + 2;
2285 consume_count (mangled);
2286 string_append (declp, *mangled);
2287 *mangled += strlen (*mangled);
2288 success = 1;
2290 else
2292 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2293 names like __Q2_3foo3bar for nested type names. So don't accept
2294 this style of constructor for cfront demangling. A GNU
2295 style member-template constructor starts with 'H'. */
2296 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2297 work -> constructor += 1;
2298 *mangled = scan + 2;
2301 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2303 /* Cfront-style parameterized type. Handled later as a signature. */
2304 success = 1;
2306 /* ARM template? */
2307 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2309 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2310 || (scan[2] == 'p' && scan[3] == 's')
2311 || (scan[2] == 'p' && scan[3] == 't')))
2313 /* EDG-style parameterized type. Handled later as a signature. */
2314 success = 1;
2316 /* EDG template? */
2317 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2319 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2320 && (scan[2] != 't'))
2322 /* Mangled name starts with "__". Skip over any leading '_' characters,
2323 then find the next "__" that separates the prefix from the signature.
2325 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2326 || (arm_special (mangled, declp) == 0))
2328 while (*scan == '_')
2330 scan++;
2332 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2334 /* No separator (I.E. "__not_mangled"), or empty signature
2335 (I.E. "__not_mangled_either__") */
2336 success = 0;
2338 else
2340 const char *tmp;
2342 /* Look for the LAST occurrence of __, allowing names to
2343 have the '__' sequence embedded in them. */
2344 if (!(ARM_DEMANGLING || HP_DEMANGLING))
2346 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
2347 scan = tmp;
2349 if (*(scan + 2) == '\0')
2350 success = 0;
2351 else
2352 demangle_function_name (work, mangled, declp, scan);
2356 else if (*(scan + 2) != '\0')
2358 /* Mangled name does not start with "__" but does have one somewhere
2359 in there with non empty stuff after it. Looks like a global
2360 function name. */
2361 demangle_function_name (work, mangled, declp, scan);
2363 else
2365 /* Doesn't look like a mangled name */
2366 success = 0;
2369 if (!success && (work->constructor == 2 || work->destructor == 2))
2371 string_append (declp, *mangled);
2372 *mangled += strlen (*mangled);
2373 success = 1;
2375 return (success);
2380 LOCAL FUNCTION
2382 gnu_special -- special handling of gnu mangled strings
2384 SYNOPSIS
2386 static int
2387 gnu_special (struct work_stuff *work, const char **mangled,
2388 string *declp);
2391 DESCRIPTION
2393 Process some special GNU style mangling forms that don't fit
2394 the normal pattern. For example:
2396 _$_3foo (destructor for class foo)
2397 _vt$foo (foo virtual table)
2398 _vt$foo$bar (foo::bar virtual table)
2399 __vt_foo (foo virtual table, new style with thunks)
2400 _3foo$varname (static data member)
2401 _Q22rs2tu$vw (static data member)
2402 __t6vector1Zii (constructor with template)
2403 __thunk_4__$_7ostream (virtual function thunk)
2406 static int
2407 gnu_special (work, mangled, declp)
2408 struct work_stuff *work;
2409 const char **mangled;
2410 string *declp;
2412 int n;
2413 int success = 1;
2414 const char *p;
2416 if ((*mangled)[0] == '_'
2417 && strchr (cplus_markers, (*mangled)[1]) != NULL
2418 && (*mangled)[2] == '_')
2420 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2421 (*mangled) += 3;
2422 work -> destructor += 1;
2424 else if ((*mangled)[0] == '_'
2425 && (((*mangled)[1] == '_'
2426 && (*mangled)[2] == 'v'
2427 && (*mangled)[3] == 't'
2428 && (*mangled)[4] == '_')
2429 || ((*mangled)[1] == 'v'
2430 && (*mangled)[2] == 't'
2431 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2433 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2434 and create the decl. Note that we consume the entire mangled
2435 input string, which means that demangle_signature has no work
2436 to do. */
2437 if ((*mangled)[2] == 'v')
2438 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2439 else
2440 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2441 while (**mangled != '\0')
2443 switch (**mangled)
2445 case 'Q':
2446 case 'K':
2447 success = demangle_qualified (work, mangled, declp, 0, 1);
2448 break;
2449 case 't':
2450 success = demangle_template (work, mangled, declp, 0, 1,
2452 break;
2453 default:
2454 if (isdigit((unsigned char)*mangled[0]))
2456 n = consume_count(mangled);
2457 /* We may be seeing a too-large size, or else a
2458 ".<digits>" indicating a static local symbol. In
2459 any case, declare victory and move on; *don't* try
2460 to use n to allocate. */
2461 if (n > (int) strlen (*mangled))
2463 success = 1;
2464 break;
2467 else
2469 n = strcspn (*mangled, cplus_markers);
2471 string_appendn (declp, *mangled, n);
2472 (*mangled) += n;
2475 p = strpbrk (*mangled, cplus_markers);
2476 if (success && ((p == NULL) || (p == *mangled)))
2478 if (p != NULL)
2480 string_append (declp, SCOPE_STRING (work));
2481 (*mangled)++;
2484 else
2486 success = 0;
2487 break;
2490 if (success)
2491 string_append (declp, " virtual table");
2493 else if ((*mangled)[0] == '_'
2494 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2495 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2497 /* static data member, "_3foo$varname" for example */
2498 (*mangled)++;
2499 switch (**mangled)
2501 case 'Q':
2502 case 'K':
2503 success = demangle_qualified (work, mangled, declp, 0, 1);
2504 break;
2505 case 't':
2506 success = demangle_template (work, mangled, declp, 0, 1, 1);
2507 break;
2508 default:
2509 n = consume_count (mangled);
2510 if (n < 0 || n > (long) strlen (*mangled))
2512 success = 0;
2513 break;
2515 string_appendn (declp, *mangled, n);
2516 (*mangled) += n;
2518 if (success && (p == *mangled))
2520 /* Consumed everything up to the cplus_marker, append the
2521 variable name. */
2522 (*mangled)++;
2523 string_append (declp, SCOPE_STRING (work));
2524 n = strlen (*mangled);
2525 string_appendn (declp, *mangled, n);
2526 (*mangled) += n;
2528 else
2530 success = 0;
2533 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2535 int delta;
2537 (*mangled) += 8;
2538 delta = consume_count (mangled);
2539 if (delta == -1)
2540 success = 0;
2541 else
2543 char *method = internal_cplus_demangle (work, ++*mangled);
2545 if (method)
2547 char buf[50];
2548 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2549 string_append (declp, buf);
2550 string_append (declp, method);
2551 free (method);
2552 n = strlen (*mangled);
2553 (*mangled) += n;
2555 else
2557 success = 0;
2561 else if (strncmp (*mangled, "__t", 3) == 0
2562 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2564 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2565 (*mangled) += 4;
2566 switch (**mangled)
2568 case 'Q':
2569 case 'K':
2570 success = demangle_qualified (work, mangled, declp, 0, 1);
2571 break;
2572 case 't':
2573 success = demangle_template (work, mangled, declp, 0, 1, 1);
2574 break;
2575 default:
2576 success = demangle_fund_type (work, mangled, declp);
2577 break;
2579 if (success && **mangled != '\0')
2580 success = 0;
2581 if (success)
2582 string_append (declp, p);
2584 else
2586 success = 0;
2588 return (success);
2591 static void
2592 recursively_demangle(work, mangled, result, namelength)
2593 struct work_stuff *work;
2594 const char **mangled;
2595 string *result;
2596 int namelength;
2598 char * recurse = (char *)NULL;
2599 char * recurse_dem = (char *)NULL;
2601 recurse = (char *) xmalloc (namelength + 1);
2602 memcpy (recurse, *mangled, namelength);
2603 recurse[namelength] = '\000';
2605 recurse_dem = cplus_demangle (recurse, work->options);
2607 if (recurse_dem)
2609 string_append (result, recurse_dem);
2610 free (recurse_dem);
2612 else
2614 string_appendn (result, *mangled, namelength);
2616 free (recurse);
2617 *mangled += namelength;
2622 LOCAL FUNCTION
2624 arm_special -- special handling of ARM/lucid mangled strings
2626 SYNOPSIS
2628 static int
2629 arm_special (const char **mangled,
2630 string *declp);
2633 DESCRIPTION
2635 Process some special ARM style mangling forms that don't fit
2636 the normal pattern. For example:
2638 __vtbl__3foo (foo virtual table)
2639 __vtbl__3foo__3bar (bar::foo virtual table)
2643 static int
2644 arm_special (mangled, declp)
2645 const char **mangled;
2646 string *declp;
2648 int n;
2649 int success = 1;
2650 const char *scan;
2652 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2654 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2655 and create the decl. Note that we consume the entire mangled
2656 input string, which means that demangle_signature has no work
2657 to do. */
2658 scan = *mangled + ARM_VTABLE_STRLEN;
2659 while (*scan != '\0') /* first check it can be demangled */
2661 n = consume_count (&scan);
2662 if (n == -1)
2664 return (0); /* no good */
2666 scan += n;
2667 if (scan[0] == '_' && scan[1] == '_')
2669 scan += 2;
2672 (*mangled) += ARM_VTABLE_STRLEN;
2673 while (**mangled != '\0')
2675 n = consume_count (mangled);
2676 if (n == -1
2677 || n > (long) strlen (*mangled))
2678 return 0;
2679 string_prependn (declp, *mangled, n);
2680 (*mangled) += n;
2681 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2683 string_prepend (declp, "::");
2684 (*mangled) += 2;
2687 string_append (declp, " virtual table");
2689 else
2691 success = 0;
2693 return (success);
2698 LOCAL FUNCTION
2700 demangle_qualified -- demangle 'Q' qualified name strings
2702 SYNOPSIS
2704 static int
2705 demangle_qualified (struct work_stuff *, const char *mangled,
2706 string *result, int isfuncname, int append);
2708 DESCRIPTION
2710 Demangle a qualified name, such as "Q25Outer5Inner" which is
2711 the mangled form of "Outer::Inner". The demangled output is
2712 prepended or appended to the result string according to the
2713 state of the append flag.
2715 If isfuncname is nonzero, then the qualified name we are building
2716 is going to be used as a member function name, so if it is a
2717 constructor or destructor function, append an appropriate
2718 constructor or destructor name. I.E. for the above example,
2719 the result for use as a constructor is "Outer::Inner::Inner"
2720 and the result for use as a destructor is "Outer::Inner::~Inner".
2722 BUGS
2724 Numeric conversion is ASCII dependent (FIXME).
2728 static int
2729 demangle_qualified (work, mangled, result, isfuncname, append)
2730 struct work_stuff *work;
2731 const char **mangled;
2732 string *result;
2733 int isfuncname;
2734 int append;
2736 int qualifiers = 0;
2737 int success = 1;
2738 char num[2];
2739 string temp;
2740 string last_name;
2741 int bindex = register_Btype (work);
2743 /* We only make use of ISFUNCNAME if the entity is a constructor or
2744 destructor. */
2745 isfuncname = (isfuncname
2746 && ((work->constructor & 1) || (work->destructor & 1)));
2748 string_init (&temp);
2749 string_init (&last_name);
2751 if ((*mangled)[0] == 'K')
2753 /* Squangling qualified name reuse */
2754 int idx;
2755 (*mangled)++;
2756 idx = consume_count_with_underscores (mangled);
2757 if (idx == -1 || idx >= work -> numk)
2758 success = 0;
2759 else
2760 string_append (&temp, work -> ktypevec[idx]);
2762 else
2763 switch ((*mangled)[1])
2765 case '_':
2766 /* GNU mangled name with more than 9 classes. The count is preceded
2767 by an underscore (to distinguish it from the <= 9 case) and followed
2768 by an underscore. */
2769 (*mangled)++;
2770 qualifiers = consume_count_with_underscores (mangled);
2771 if (qualifiers == -1)
2772 success = 0;
2773 break;
2775 case '1':
2776 case '2':
2777 case '3':
2778 case '4':
2779 case '5':
2780 case '6':
2781 case '7':
2782 case '8':
2783 case '9':
2784 /* The count is in a single digit. */
2785 num[0] = (*mangled)[1];
2786 num[1] = '\0';
2787 qualifiers = atoi (num);
2789 /* If there is an underscore after the digit, skip it. This is
2790 said to be for ARM-qualified names, but the ARM makes no
2791 mention of such an underscore. Perhaps cfront uses one. */
2792 if ((*mangled)[2] == '_')
2794 (*mangled)++;
2796 (*mangled) += 2;
2797 break;
2799 case '0':
2800 default:
2801 success = 0;
2804 if (!success)
2805 return success;
2807 /* Pick off the names and collect them in the temp buffer in the order
2808 in which they are found, separated by '::'. */
2810 while (qualifiers-- > 0)
2812 int remember_K = 1;
2813 string_clear (&last_name);
2815 if (*mangled[0] == '_')
2816 (*mangled)++;
2818 if (*mangled[0] == 't')
2820 /* Here we always append to TEMP since we will want to use
2821 the template name without the template parameters as a
2822 constructor or destructor name. The appropriate
2823 (parameter-less) value is returned by demangle_template
2824 in LAST_NAME. We do not remember the template type here,
2825 in order to match the G++ mangling algorithm. */
2826 success = demangle_template(work, mangled, &temp,
2827 &last_name, 1, 0);
2828 if (!success)
2829 break;
2831 else if (*mangled[0] == 'K')
2833 int idx;
2834 (*mangled)++;
2835 idx = consume_count_with_underscores (mangled);
2836 if (idx == -1 || idx >= work->numk)
2837 success = 0;
2838 else
2839 string_append (&temp, work->ktypevec[idx]);
2840 remember_K = 0;
2842 if (!success) break;
2844 else
2846 if (EDG_DEMANGLING)
2848 int namelength;
2849 /* Now recursively demangle the qualifier
2850 * This is necessary to deal with templates in
2851 * mangling styles like EDG */
2852 namelength = consume_count (mangled);
2853 if (namelength == -1)
2855 success = 0;
2856 break;
2858 recursively_demangle(work, mangled, &temp, namelength);
2860 else
2862 success = do_type (work, mangled, &last_name);
2863 if (!success)
2864 break;
2865 string_appends (&temp, &last_name);
2869 if (remember_K)
2870 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2872 if (qualifiers > 0)
2873 string_append (&temp, SCOPE_STRING (work));
2876 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2878 /* If we are using the result as a function name, we need to append
2879 the appropriate '::' separated constructor or destructor name.
2880 We do this here because this is the most convenient place, where
2881 we already have a pointer to the name and the length of the name. */
2883 if (isfuncname)
2885 string_append (&temp, SCOPE_STRING (work));
2886 if (work -> destructor & 1)
2887 string_append (&temp, "~");
2888 string_appends (&temp, &last_name);
2891 /* Now either prepend the temp buffer to the result, or append it,
2892 depending upon the state of the append flag. */
2894 if (append)
2895 string_appends (result, &temp);
2896 else
2898 if (!STRING_EMPTY (result))
2899 string_append (&temp, SCOPE_STRING (work));
2900 string_prepends (result, &temp);
2903 string_delete (&last_name);
2904 string_delete (&temp);
2905 return (success);
2910 LOCAL FUNCTION
2912 get_count -- convert an ascii count to integer, consuming tokens
2914 SYNOPSIS
2916 static int
2917 get_count (const char **type, int *count)
2919 DESCRIPTION
2921 Assume that *type points at a count in a mangled name; set
2922 *count to its value, and set *type to the next character after
2923 the count. There are some weird rules in effect here.
2925 If *type does not point at a string of digits, return zero.
2927 If *type points at a string of digits followed by an
2928 underscore, set *count to their value as an integer, advance
2929 *type to point *after the underscore, and return 1.
2931 If *type points at a string of digits not followed by an
2932 underscore, consume only the first digit. Set *count to its
2933 value as an integer, leave *type pointing after that digit,
2934 and return 1.
2936 The excuse for this odd behavior: in the ARM and HP demangling
2937 styles, a type can be followed by a repeat count of the form
2938 `Nxy', where:
2940 `x' is a single digit specifying how many additional copies
2941 of the type to append to the argument list, and
2943 `y' is one or more digits, specifying the zero-based index of
2944 the first repeated argument in the list. Yes, as you're
2945 unmangling the name you can figure this out yourself, but
2946 it's there anyway.
2948 So, for example, in `bar__3fooFPiN51', the first argument is a
2949 pointer to an integer (`Pi'), and then the next five arguments
2950 are the same (`N5'), and the first repeat is the function's
2951 second argument (`1').
2954 static int
2955 get_count (type, count)
2956 const char **type;
2957 int *count;
2959 const char *p;
2960 int n;
2962 if (!isdigit ((unsigned char)**type))
2963 return (0);
2964 else
2966 *count = **type - '0';
2967 (*type)++;
2968 if (isdigit ((unsigned char)**type))
2970 p = *type;
2971 n = *count;
2974 n *= 10;
2975 n += *p - '0';
2976 p++;
2978 while (isdigit ((unsigned char)*p));
2979 if (*p == '_')
2981 *type = p + 1;
2982 *count = n;
2986 return (1);
2989 /* RESULT will be initialised here; it will be freed on failure. The
2990 value returned is really a type_kind_t. */
2992 static int
2993 do_type (work, mangled, result)
2994 struct work_stuff *work;
2995 const char **mangled;
2996 string *result;
2998 int n;
2999 int done;
3000 int success;
3001 string decl;
3002 const char *remembered_type;
3003 int type_quals;
3004 string btype;
3005 type_kind_t tk = tk_none;
3007 string_init (&btype);
3008 string_init (&decl);
3009 string_init (result);
3011 done = 0;
3012 success = 1;
3013 while (success && !done)
3015 int member;
3016 switch (**mangled)
3019 /* A pointer type */
3020 case 'P':
3021 case 'p':
3022 (*mangled)++;
3023 if (! (work -> options & DMGL_JAVA))
3024 string_prepend (&decl, "*");
3025 if (tk == tk_none)
3026 tk = tk_pointer;
3027 break;
3029 /* A reference type */
3030 case 'R':
3031 (*mangled)++;
3032 string_prepend (&decl, "&");
3033 if (tk == tk_none)
3034 tk = tk_reference;
3035 break;
3037 /* An array */
3038 case 'A':
3040 ++(*mangled);
3041 if (!STRING_EMPTY (&decl)
3042 && (decl.b[0] == '*' || decl.b[0] == '&'))
3044 string_prepend (&decl, "(");
3045 string_append (&decl, ")");
3047 string_append (&decl, "[");
3048 if (**mangled != '_')
3049 success = demangle_template_value_parm (work, mangled, &decl,
3050 tk_integral);
3051 if (**mangled == '_')
3052 ++(*mangled);
3053 string_append (&decl, "]");
3054 break;
3057 /* A back reference to a previously seen type */
3058 case 'T':
3059 (*mangled)++;
3060 if (!get_count (mangled, &n) || n >= work -> ntypes)
3062 success = 0;
3064 else
3066 remembered_type = work -> typevec[n];
3067 mangled = &remembered_type;
3069 break;
3071 /* A function */
3072 case 'F':
3073 (*mangled)++;
3074 if (!STRING_EMPTY (&decl)
3075 && (decl.b[0] == '*' || decl.b[0] == '&'))
3077 string_prepend (&decl, "(");
3078 string_append (&decl, ")");
3080 /* After picking off the function args, we expect to either find the
3081 function return type (preceded by an '_') or the end of the
3082 string. */
3083 if (!demangle_nested_args (work, mangled, &decl)
3084 || (**mangled != '_' && **mangled != '\0'))
3086 success = 0;
3087 break;
3089 if (success && (**mangled == '_'))
3090 (*mangled)++;
3091 break;
3093 case 'M':
3094 case 'O':
3096 type_quals = TYPE_UNQUALIFIED;
3098 member = **mangled == 'M';
3099 (*mangled)++;
3101 string_append (&decl, ")");
3103 /* We don't need to prepend `::' for a qualified name;
3104 demangle_qualified will do that for us. */
3105 if (**mangled != 'Q')
3106 string_prepend (&decl, SCOPE_STRING (work));
3108 if (isdigit ((unsigned char)**mangled))
3110 n = consume_count (mangled);
3111 if (n == -1
3112 || (int) strlen (*mangled) < n)
3114 success = 0;
3115 break;
3117 string_prependn (&decl, *mangled, n);
3118 *mangled += n;
3120 else if (**mangled == 'X' || **mangled == 'Y')
3122 string temp;
3123 do_type (work, mangled, &temp);
3124 string_prepends (&decl, &temp);
3126 else if (**mangled == 't')
3128 string temp;
3129 string_init (&temp);
3130 success = demangle_template (work, mangled, &temp,
3131 NULL, 1, 1);
3132 if (success)
3134 string_prependn (&decl, temp.b, temp.p - temp.b);
3135 string_clear (&temp);
3137 else
3138 break;
3140 else if (**mangled == 'Q')
3142 success = demangle_qualified (work, mangled, &decl,
3143 /*isfuncnam=*/0,
3144 /*append=*/0);
3145 if (!success)
3146 break;
3148 else
3150 success = 0;
3151 break;
3154 string_prepend (&decl, "(");
3155 if (member)
3157 switch (**mangled)
3159 case 'C':
3160 case 'V':
3161 case 'u':
3162 type_quals |= code_for_qualifier (**mangled);
3163 (*mangled)++;
3164 break;
3166 default:
3167 break;
3170 if (*(*mangled)++ != 'F')
3172 success = 0;
3173 break;
3176 if ((member && !demangle_nested_args (work, mangled, &decl))
3177 || **mangled != '_')
3179 success = 0;
3180 break;
3182 (*mangled)++;
3183 if (! PRINT_ANSI_QUALIFIERS)
3185 break;
3187 if (type_quals != TYPE_UNQUALIFIED)
3189 APPEND_BLANK (&decl);
3190 string_append (&decl, qualifier_string (type_quals));
3192 break;
3194 case 'G':
3195 (*mangled)++;
3196 break;
3198 case 'C':
3199 case 'V':
3200 case 'u':
3201 if (PRINT_ANSI_QUALIFIERS)
3203 if (!STRING_EMPTY (&decl))
3204 string_prepend (&decl, " ");
3206 string_prepend (&decl, demangle_qualifier (**mangled));
3208 (*mangled)++;
3209 break;
3214 /* fall through */
3215 default:
3216 done = 1;
3217 break;
3221 if (success) switch (**mangled)
3223 /* A qualified name, such as "Outer::Inner". */
3224 case 'Q':
3225 case 'K':
3227 success = demangle_qualified (work, mangled, result, 0, 1);
3228 break;
3231 /* A back reference to a previously seen squangled type */
3232 case 'B':
3233 (*mangled)++;
3234 if (!get_count (mangled, &n) || n >= work -> numb)
3235 success = 0;
3236 else
3237 string_append (result, work->btypevec[n]);
3238 break;
3240 case 'X':
3241 case 'Y':
3242 /* A template parm. We substitute the corresponding argument. */
3244 int idx;
3246 (*mangled)++;
3247 idx = consume_count_with_underscores (mangled);
3249 if (idx == -1
3250 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3251 || consume_count_with_underscores (mangled) == -1)
3253 success = 0;
3254 break;
3257 if (work->tmpl_argvec)
3258 string_append (result, work->tmpl_argvec[idx]);
3259 else
3260 string_append_template_idx (result, idx);
3262 success = 1;
3264 break;
3266 default:
3267 success = demangle_fund_type (work, mangled, result);
3268 if (tk == tk_none)
3269 tk = (type_kind_t) success;
3270 break;
3273 if (success)
3275 if (!STRING_EMPTY (&decl))
3277 string_append (result, " ");
3278 string_appends (result, &decl);
3281 else
3282 string_delete (result);
3283 string_delete (&decl);
3285 if (success)
3286 /* Assume an integral type, if we're not sure. */
3287 return (int) ((tk == tk_none) ? tk_integral : tk);
3288 else
3289 return 0;
3292 /* Given a pointer to a type string that represents a fundamental type
3293 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3294 string in which the demangled output is being built in RESULT, and
3295 the WORK structure, decode the types and add them to the result.
3297 For example:
3299 "Ci" => "const int"
3300 "Sl" => "signed long"
3301 "CUs" => "const unsigned short"
3303 The value returned is really a type_kind_t. */
3305 static int
3306 demangle_fund_type (work, mangled, result)
3307 struct work_stuff *work;
3308 const char **mangled;
3309 string *result;
3311 int done = 0;
3312 int success = 1;
3313 char buf[10];
3314 int dec = 0;
3315 string btype;
3316 type_kind_t tk = tk_integral;
3318 string_init (&btype);
3320 /* First pick off any type qualifiers. There can be more than one. */
3322 while (!done)
3324 switch (**mangled)
3326 case 'C':
3327 case 'V':
3328 case 'u':
3329 if (PRINT_ANSI_QUALIFIERS)
3331 if (!STRING_EMPTY (result))
3332 string_prepend (result, " ");
3333 string_prepend (result, demangle_qualifier (**mangled));
3335 (*mangled)++;
3336 break;
3337 case 'U':
3338 (*mangled)++;
3339 APPEND_BLANK (result);
3340 string_append (result, "unsigned");
3341 break;
3342 case 'S': /* signed char only */
3343 (*mangled)++;
3344 APPEND_BLANK (result);
3345 string_append (result, "signed");
3346 break;
3347 case 'J':
3348 (*mangled)++;
3349 APPEND_BLANK (result);
3350 string_append (result, "__complex");
3351 break;
3352 default:
3353 done = 1;
3354 break;
3358 /* Now pick off the fundamental type. There can be only one. */
3360 switch (**mangled)
3362 case '\0':
3363 case '_':
3364 break;
3365 case 'v':
3366 (*mangled)++;
3367 APPEND_BLANK (result);
3368 string_append (result, "void");
3369 break;
3370 case 'x':
3371 (*mangled)++;
3372 APPEND_BLANK (result);
3373 string_append (result, "long long");
3374 break;
3375 case 'l':
3376 (*mangled)++;
3377 APPEND_BLANK (result);
3378 string_append (result, "long");
3379 break;
3380 case 'i':
3381 (*mangled)++;
3382 APPEND_BLANK (result);
3383 string_append (result, "int");
3384 break;
3385 case 's':
3386 (*mangled)++;
3387 APPEND_BLANK (result);
3388 string_append (result, "short");
3389 break;
3390 case 'b':
3391 (*mangled)++;
3392 APPEND_BLANK (result);
3393 string_append (result, "bool");
3394 tk = tk_bool;
3395 break;
3396 case 'c':
3397 (*mangled)++;
3398 APPEND_BLANK (result);
3399 string_append (result, "char");
3400 tk = tk_char;
3401 break;
3402 case 'w':
3403 (*mangled)++;
3404 APPEND_BLANK (result);
3405 string_append (result, "wchar_t");
3406 tk = tk_char;
3407 break;
3408 case 'r':
3409 (*mangled)++;
3410 APPEND_BLANK (result);
3411 string_append (result, "long double");
3412 tk = tk_real;
3413 break;
3414 case 'd':
3415 (*mangled)++;
3416 APPEND_BLANK (result);
3417 string_append (result, "double");
3418 tk = tk_real;
3419 break;
3420 case 'f':
3421 (*mangled)++;
3422 APPEND_BLANK (result);
3423 string_append (result, "float");
3424 tk = tk_real;
3425 break;
3426 case 'G':
3427 (*mangled)++;
3428 if (!isdigit ((unsigned char)**mangled))
3430 success = 0;
3431 break;
3433 case 'I':
3434 (*mangled)++;
3435 if (**mangled == '_')
3437 int i;
3438 (*mangled)++;
3439 for (i = 0;
3440 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3441 (*mangled)++, i++)
3442 buf[i] = **mangled;
3443 if (**mangled != '_')
3445 success = 0;
3446 break;
3448 buf[i] = '\0';
3449 (*mangled)++;
3451 else
3453 strncpy (buf, *mangled, 2);
3454 buf[2] = '\0';
3455 *mangled += min (strlen (*mangled), 2);
3457 sscanf (buf, "%x", &dec);
3458 sprintf (buf, "int%i_t", dec);
3459 APPEND_BLANK (result);
3460 string_append (result, buf);
3461 break;
3463 /* fall through */
3464 /* An explicit type, such as "6mytype" or "7integer" */
3465 case '0':
3466 case '1':
3467 case '2':
3468 case '3':
3469 case '4':
3470 case '5':
3471 case '6':
3472 case '7':
3473 case '8':
3474 case '9':
3476 int bindex = register_Btype (work);
3477 string btype;
3478 string_init (&btype);
3479 if (demangle_class_name (work, mangled, &btype)) {
3480 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3481 APPEND_BLANK (result);
3482 string_appends (result, &btype);
3484 else
3485 success = 0;
3486 string_delete (&btype);
3487 break;
3489 case 't':
3491 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3492 string_appends (result, &btype);
3493 break;
3495 default:
3496 success = 0;
3497 break;
3500 return success ? ((int) tk) : 0;
3504 /* Handle a template's value parameter for HP aCC (extension from ARM)
3505 **mangled points to 'S' or 'U' */
3507 static int
3508 do_hpacc_template_const_value (work, mangled, result)
3509 struct work_stuff *work ATTRIBUTE_UNUSED;
3510 const char **mangled;
3511 string *result;
3513 int unsigned_const;
3515 if (**mangled != 'U' && **mangled != 'S')
3516 return 0;
3518 unsigned_const = (**mangled == 'U');
3520 (*mangled)++;
3522 switch (**mangled)
3524 case 'N':
3525 string_append (result, "-");
3526 /* fall through */
3527 case 'P':
3528 (*mangled)++;
3529 break;
3530 case 'M':
3531 /* special case for -2^31 */
3532 string_append (result, "-2147483648");
3533 (*mangled)++;
3534 return 1;
3535 default:
3536 return 0;
3539 /* We have to be looking at an integer now */
3540 if (!(isdigit ((unsigned char)**mangled)))
3541 return 0;
3543 /* We only deal with integral values for template
3544 parameters -- so it's OK to look only for digits */
3545 while (isdigit ((unsigned char)**mangled))
3547 char_str[0] = **mangled;
3548 string_append (result, char_str);
3549 (*mangled)++;
3552 if (unsigned_const)
3553 string_append (result, "U");
3555 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3556 with L or LL suffixes. pai/1997-09-03 */
3558 return 1; /* success */
3561 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3562 **mangled is pointing to the 'A' */
3564 static int
3565 do_hpacc_template_literal (work, mangled, result)
3566 struct work_stuff *work;
3567 const char **mangled;
3568 string *result;
3570 int literal_len = 0;
3571 char * recurse;
3572 char * recurse_dem;
3574 if (**mangled != 'A')
3575 return 0;
3577 (*mangled)++;
3579 literal_len = consume_count (mangled);
3581 if (literal_len <= 0)
3582 return 0;
3584 /* Literal parameters are names of arrays, functions, etc. and the
3585 canonical representation uses the address operator */
3586 string_append (result, "&");
3588 /* Now recursively demangle the literal name */
3589 recurse = (char *) xmalloc (literal_len + 1);
3590 memcpy (recurse, *mangled, literal_len);
3591 recurse[literal_len] = '\000';
3593 recurse_dem = cplus_demangle (recurse, work->options);
3595 if (recurse_dem)
3597 string_append (result, recurse_dem);
3598 free (recurse_dem);
3600 else
3602 string_appendn (result, *mangled, literal_len);
3604 (*mangled) += literal_len;
3605 free (recurse);
3607 return 1;
3610 static int
3611 snarf_numeric_literal (args, arg)
3612 const char ** args;
3613 string * arg;
3615 if (**args == '-')
3617 char_str[0] = '-';
3618 string_append (arg, char_str);
3619 (*args)++;
3621 else if (**args == '+')
3622 (*args)++;
3624 if (!isdigit ((unsigned char)**args))
3625 return 0;
3627 while (isdigit ((unsigned char)**args))
3629 char_str[0] = **args;
3630 string_append (arg, char_str);
3631 (*args)++;
3634 return 1;
3637 /* Demangle the next argument, given by MANGLED into RESULT, which
3638 *should be an uninitialized* string. It will be initialized here,
3639 and free'd should anything go wrong. */
3641 static int
3642 do_arg (work, mangled, result)
3643 struct work_stuff *work;
3644 const char **mangled;
3645 string *result;
3647 /* Remember where we started so that we can record the type, for
3648 non-squangling type remembering. */
3649 const char *start = *mangled;
3651 string_init (result);
3653 if (work->nrepeats > 0)
3655 --work->nrepeats;
3657 if (work->previous_argument == 0)
3658 return 0;
3660 /* We want to reissue the previous type in this argument list. */
3661 string_appends (result, work->previous_argument);
3662 return 1;
3665 if (**mangled == 'n')
3667 /* A squangling-style repeat. */
3668 (*mangled)++;
3669 work->nrepeats = consume_count(mangled);
3671 if (work->nrepeats <= 0)
3672 /* This was not a repeat count after all. */
3673 return 0;
3675 if (work->nrepeats > 9)
3677 if (**mangled != '_')
3678 /* The repeat count should be followed by an '_' in this
3679 case. */
3680 return 0;
3681 else
3682 (*mangled)++;
3685 /* Now, the repeat is all set up. */
3686 return do_arg (work, mangled, result);
3689 /* Save the result in WORK->previous_argument so that we can find it
3690 if it's repeated. Note that saving START is not good enough: we
3691 do not want to add additional types to the back-referenceable
3692 type vector when processing a repeated type. */
3693 if (work->previous_argument)
3694 string_clear (work->previous_argument);
3695 else
3697 work->previous_argument = (string*) xmalloc (sizeof (string));
3698 string_init (work->previous_argument);
3701 if (!do_type (work, mangled, work->previous_argument))
3702 return 0;
3704 string_appends (result, work->previous_argument);
3706 remember_type (work, start, *mangled - start);
3707 return 1;
3710 static void
3711 remember_type (work, start, len)
3712 struct work_stuff *work;
3713 const char *start;
3714 int len;
3716 char *tem;
3718 if (work->forgetting_types)
3719 return;
3721 if (work -> ntypes >= work -> typevec_size)
3723 if (work -> typevec_size == 0)
3725 work -> typevec_size = 3;
3726 work -> typevec
3727 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3729 else
3731 work -> typevec_size *= 2;
3732 work -> typevec
3733 = (char **) xrealloc ((char *)work -> typevec,
3734 sizeof (char *) * work -> typevec_size);
3737 tem = xmalloc (len + 1);
3738 memcpy (tem, start, len);
3739 tem[len] = '\0';
3740 work -> typevec[work -> ntypes++] = tem;
3744 /* Remember a K type class qualifier. */
3745 static void
3746 remember_Ktype (work, start, len)
3747 struct work_stuff *work;
3748 const char *start;
3749 int len;
3751 char *tem;
3753 if (work -> numk >= work -> ksize)
3755 if (work -> ksize == 0)
3757 work -> ksize = 5;
3758 work -> ktypevec
3759 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3761 else
3763 work -> ksize *= 2;
3764 work -> ktypevec
3765 = (char **) xrealloc ((char *)work -> ktypevec,
3766 sizeof (char *) * work -> ksize);
3769 tem = xmalloc (len + 1);
3770 memcpy (tem, start, len);
3771 tem[len] = '\0';
3772 work -> ktypevec[work -> numk++] = tem;
3775 /* Register a B code, and get an index for it. B codes are registered
3776 as they are seen, rather than as they are completed, so map<temp<char> >
3777 registers map<temp<char> > as B0, and temp<char> as B1 */
3779 static int
3780 register_Btype (work)
3781 struct work_stuff *work;
3783 int ret;
3785 if (work -> numb >= work -> bsize)
3787 if (work -> bsize == 0)
3789 work -> bsize = 5;
3790 work -> btypevec
3791 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3793 else
3795 work -> bsize *= 2;
3796 work -> btypevec
3797 = (char **) xrealloc ((char *)work -> btypevec,
3798 sizeof (char *) * work -> bsize);
3801 ret = work -> numb++;
3802 work -> btypevec[ret] = NULL;
3803 return(ret);
3806 /* Store a value into a previously registered B code type. */
3808 static void
3809 remember_Btype (work, start, len, index)
3810 struct work_stuff *work;
3811 const char *start;
3812 int len, index;
3814 char *tem;
3816 tem = xmalloc (len + 1);
3817 memcpy (tem, start, len);
3818 tem[len] = '\0';
3819 work -> btypevec[index] = tem;
3822 /* Lose all the info related to B and K type codes. */
3823 static void
3824 forget_B_and_K_types (work)
3825 struct work_stuff *work;
3827 int i;
3829 while (work -> numk > 0)
3831 i = --(work -> numk);
3832 if (work -> ktypevec[i] != NULL)
3834 free (work -> ktypevec[i]);
3835 work -> ktypevec[i] = NULL;
3839 while (work -> numb > 0)
3841 i = --(work -> numb);
3842 if (work -> btypevec[i] != NULL)
3844 free (work -> btypevec[i]);
3845 work -> btypevec[i] = NULL;
3849 /* Forget the remembered types, but not the type vector itself. */
3851 static void
3852 forget_types (work)
3853 struct work_stuff *work;
3855 int i;
3857 while (work -> ntypes > 0)
3859 i = --(work -> ntypes);
3860 if (work -> typevec[i] != NULL)
3862 free (work -> typevec[i]);
3863 work -> typevec[i] = NULL;
3868 /* Process the argument list part of the signature, after any class spec
3869 has been consumed, as well as the first 'F' character (if any). For
3870 example:
3872 "__als__3fooRT0" => process "RT0"
3873 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3875 DECLP must be already initialised, usually non-empty. It won't be freed
3876 on failure.
3878 Note that g++ differs significantly from ARM and lucid style mangling
3879 with regards to references to previously seen types. For example, given
3880 the source fragment:
3882 class foo {
3883 public:
3884 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3887 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3888 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3890 g++ produces the names:
3892 __3fooiRT0iT2iT2
3893 foo__FiR3fooiT1iT1
3895 while lcc (and presumably other ARM style compilers as well) produces:
3897 foo__FiR3fooT1T2T1T2
3898 __ct__3fooFiR3fooT1T2T1T2
3900 Note that g++ bases its type numbers starting at zero and counts all
3901 previously seen types, while lucid/ARM bases its type numbers starting
3902 at one and only considers types after it has seen the 'F' character
3903 indicating the start of the function args. For lucid/ARM style, we
3904 account for this difference by discarding any previously seen types when
3905 we see the 'F' character, and subtracting one from the type number
3906 reference.
3910 static int
3911 demangle_args (work, mangled, declp)
3912 struct work_stuff *work;
3913 const char **mangled;
3914 string *declp;
3916 string arg;
3917 int need_comma = 0;
3918 int r;
3919 int t;
3920 const char *tem;
3921 char temptype;
3923 if (PRINT_ARG_TYPES)
3925 string_append (declp, "(");
3926 if (**mangled == '\0')
3928 string_append (declp, "void");
3932 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3933 || work->nrepeats > 0)
3935 if ((**mangled == 'N') || (**mangled == 'T'))
3937 temptype = *(*mangled)++;
3939 if (temptype == 'N')
3941 if (!get_count (mangled, &r))
3943 return (0);
3946 else
3948 r = 1;
3950 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3952 /* If we have 10 or more types we might have more than a 1 digit
3953 index so we'll have to consume the whole count here. This
3954 will lose if the next thing is a type name preceded by a
3955 count but it's impossible to demangle that case properly
3956 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3957 Pc, ...)" or "(..., type12, char *, ...)" */
3958 if ((t = consume_count(mangled)) <= 0)
3960 return (0);
3963 else
3965 if (!get_count (mangled, &t))
3967 return (0);
3970 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3972 t--;
3974 /* Validate the type index. Protect against illegal indices from
3975 malformed type strings. */
3976 if ((t < 0) || (t >= work -> ntypes))
3978 return (0);
3980 while (work->nrepeats > 0 || --r >= 0)
3982 tem = work -> typevec[t];
3983 if (need_comma && PRINT_ARG_TYPES)
3985 string_append (declp, ", ");
3987 if (!do_arg (work, &tem, &arg))
3989 return (0);
3991 if (PRINT_ARG_TYPES)
3993 string_appends (declp, &arg);
3995 string_delete (&arg);
3996 need_comma = 1;
3999 else
4001 if (need_comma && PRINT_ARG_TYPES)
4002 string_append (declp, ", ");
4003 if (!do_arg (work, mangled, &arg))
4004 return (0);
4005 if (PRINT_ARG_TYPES)
4006 string_appends (declp, &arg);
4007 string_delete (&arg);
4008 need_comma = 1;
4012 if (**mangled == 'e')
4014 (*mangled)++;
4015 if (PRINT_ARG_TYPES)
4017 if (need_comma)
4019 string_append (declp, ",");
4021 string_append (declp, "...");
4025 if (PRINT_ARG_TYPES)
4027 string_append (declp, ")");
4029 return (1);
4032 /* Like demangle_args, but for demangling the argument lists of function
4033 and method pointers or references, not top-level declarations. */
4035 static int
4036 demangle_nested_args (work, mangled, declp)
4037 struct work_stuff *work;
4038 const char **mangled;
4039 string *declp;
4041 string* saved_previous_argument;
4042 int result;
4043 int saved_nrepeats;
4045 /* The G++ name-mangling algorithm does not remember types on nested
4046 argument lists, unless -fsquangling is used, and in that case the
4047 type vector updated by remember_type is not used. So, we turn
4048 off remembering of types here. */
4049 ++work->forgetting_types;
4051 /* For the repeat codes used with -fsquangling, we must keep track of
4052 the last argument. */
4053 saved_previous_argument = work->previous_argument;
4054 saved_nrepeats = work->nrepeats;
4055 work->previous_argument = 0;
4056 work->nrepeats = 0;
4058 /* Actually demangle the arguments. */
4059 result = demangle_args (work, mangled, declp);
4061 /* Restore the previous_argument field. */
4062 if (work->previous_argument)
4063 string_delete (work->previous_argument);
4064 work->previous_argument = saved_previous_argument;
4065 --work->forgetting_types;
4066 work->nrepeats = saved_nrepeats;
4068 return result;
4071 static void
4072 demangle_function_name (work, mangled, declp, scan)
4073 struct work_stuff *work;
4074 const char **mangled;
4075 string *declp;
4076 const char *scan;
4078 size_t i;
4079 string type;
4080 const char *tem;
4082 string_appendn (declp, (*mangled), scan - (*mangled));
4083 string_need (declp, 1);
4084 *(declp -> p) = '\0';
4086 /* Consume the function name, including the "__" separating the name
4087 from the signature. We are guaranteed that SCAN points to the
4088 separator. */
4090 (*mangled) = scan + 2;
4091 /* We may be looking at an instantiation of a template function:
4092 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4093 following _F marks the start of the function arguments. Handle
4094 the template arguments first. */
4096 if (HP_DEMANGLING && (**mangled == 'X'))
4098 demangle_arm_hp_template (work, mangled, 0, declp);
4099 /* This leaves MANGLED pointing to the 'F' marking func args */
4102 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4105 /* See if we have an ARM style constructor or destructor operator.
4106 If so, then just record it, clear the decl, and return.
4107 We can't build the actual constructor/destructor decl until later,
4108 when we recover the class name from the signature. */
4110 if (strcmp (declp -> b, "__ct") == 0)
4112 work -> constructor += 1;
4113 string_clear (declp);
4114 return;
4116 else if (strcmp (declp -> b, "__dt") == 0)
4118 work -> destructor += 1;
4119 string_clear (declp);
4120 return;
4124 if (declp->p - declp->b >= 3
4125 && declp->b[0] == 'o'
4126 && declp->b[1] == 'p'
4127 && strchr (cplus_markers, declp->b[2]) != NULL)
4129 /* see if it's an assignment expression */
4130 if (declp->p - declp->b >= 10 /* op$assign_ */
4131 && memcmp (declp->b + 3, "assign_", 7) == 0)
4133 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4135 int len = declp->p - declp->b - 10;
4136 if ((int) strlen (optable[i].in) == len
4137 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4139 string_clear (declp);
4140 string_append (declp, "operator");
4141 string_append (declp, optable[i].out);
4142 string_append (declp, "=");
4143 break;
4147 else
4149 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4151 int len = declp->p - declp->b - 3;
4152 if ((int) strlen (optable[i].in) == len
4153 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4155 string_clear (declp);
4156 string_append (declp, "operator");
4157 string_append (declp, optable[i].out);
4158 break;
4163 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4164 && strchr (cplus_markers, declp->b[4]) != NULL)
4166 /* type conversion operator */
4167 tem = declp->b + 5;
4168 if (do_type (work, &tem, &type))
4170 string_clear (declp);
4171 string_append (declp, "operator ");
4172 string_appends (declp, &type);
4173 string_delete (&type);
4176 else if (declp->b[0] == '_' && declp->b[1] == '_'
4177 && declp->b[2] == 'o' && declp->b[3] == 'p')
4179 /* ANSI. */
4180 /* type conversion operator. */
4181 tem = declp->b + 4;
4182 if (do_type (work, &tem, &type))
4184 string_clear (declp);
4185 string_append (declp, "operator ");
4186 string_appends (declp, &type);
4187 string_delete (&type);
4190 else if (declp->b[0] == '_' && declp->b[1] == '_'
4191 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4192 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4194 if (declp->b[4] == '\0')
4196 /* Operator. */
4197 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4199 if (strlen (optable[i].in) == 2
4200 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4202 string_clear (declp);
4203 string_append (declp, "operator");
4204 string_append (declp, optable[i].out);
4205 break;
4209 else
4211 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4213 /* Assignment. */
4214 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4216 if (strlen (optable[i].in) == 3
4217 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4219 string_clear (declp);
4220 string_append (declp, "operator");
4221 string_append (declp, optable[i].out);
4222 break;
4230 /* a mini string-handling package */
4232 static void
4233 string_need (s, n)
4234 string *s;
4235 int n;
4237 int tem;
4239 if (s->b == NULL)
4241 if (n < 32)
4243 n = 32;
4245 s->p = s->b = xmalloc (n);
4246 s->e = s->b + n;
4248 else if (s->e - s->p < n)
4250 tem = s->p - s->b;
4251 n += tem;
4252 n *= 2;
4253 s->b = xrealloc (s->b, n);
4254 s->p = s->b + tem;
4255 s->e = s->b + n;
4259 static void
4260 string_delete (s)
4261 string *s;
4263 if (s->b != NULL)
4265 free (s->b);
4266 s->b = s->e = s->p = NULL;
4270 static void
4271 string_init (s)
4272 string *s;
4274 s->b = s->p = s->e = NULL;
4277 static void
4278 string_clear (s)
4279 string *s;
4281 s->p = s->b;
4284 #if 0
4286 static int
4287 string_empty (s)
4288 string *s;
4290 return (s->b == s->p);
4293 #endif
4295 static void
4296 string_append (p, s)
4297 string *p;
4298 const char *s;
4300 int n;
4301 if (s == NULL || *s == '\0')
4302 return;
4303 n = strlen (s);
4304 string_need (p, n);
4305 memcpy (p->p, s, n);
4306 p->p += n;
4309 static void
4310 string_appends (p, s)
4311 string *p, *s;
4313 int n;
4315 if (s->b != s->p)
4317 n = s->p - s->b;
4318 string_need (p, n);
4319 memcpy (p->p, s->b, n);
4320 p->p += n;
4324 static void
4325 string_appendn (p, s, n)
4326 string *p;
4327 const char *s;
4328 int n;
4330 if (n != 0)
4332 string_need (p, n);
4333 memcpy (p->p, s, n);
4334 p->p += n;
4338 static void
4339 string_prepend (p, s)
4340 string *p;
4341 const char *s;
4343 if (s != NULL && *s != '\0')
4345 string_prependn (p, s, strlen (s));
4349 static void
4350 string_prepends (p, s)
4351 string *p, *s;
4353 if (s->b != s->p)
4355 string_prependn (p, s->b, s->p - s->b);
4359 static void
4360 string_prependn (p, s, n)
4361 string *p;
4362 const char *s;
4363 int n;
4365 char *q;
4367 if (n != 0)
4369 string_need (p, n);
4370 for (q = p->p - 1; q >= p->b; q--)
4372 q[n] = q[0];
4374 memcpy (p->b, s, n);
4375 p->p += n;
4379 static void
4380 string_append_template_idx (s, idx)
4381 string *s;
4382 int idx;
4384 char buf[INTBUF_SIZE + 1 /* 'T' */];
4385 sprintf(buf, "T%d", idx);
4386 string_append (s, buf);
4389 /* To generate a standalone demangler program for testing purposes,
4390 just compile and link this file with -DMAIN and libiberty.a. When
4391 run, it demangles each command line arg, or each stdin string, and
4392 prints the result on stdout. */
4394 #ifdef MAIN
4396 #include "getopt.h"
4398 static const char *program_name;
4399 static const char *program_version = VERSION;
4400 static int flags = DMGL_PARAMS | DMGL_ANSI;
4402 static void demangle_it PARAMS ((char *));
4403 static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
4404 static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
4406 static void
4407 demangle_it (mangled_name)
4408 char *mangled_name;
4410 char *result;
4412 result = cplus_demangle (mangled_name, flags);
4413 if (result == NULL)
4415 printf ("%s\n", mangled_name);
4417 else
4419 printf ("%s\n", result);
4420 free (result);
4424 static void
4425 usage (stream, status)
4426 FILE *stream;
4427 int status;
4429 fprintf (stream, "\
4430 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4431 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4432 [--help] [--version] [arg...]\n",
4433 program_name);
4434 exit (status);
4437 #define MBUF_SIZE 32767
4438 char mbuffer[MBUF_SIZE];
4440 /* Defined in the automatically-generated underscore.c. */
4441 extern int prepends_underscore;
4443 int strip_underscore = 0;
4445 static struct option long_options[] = {
4446 {"strip-underscores", no_argument, 0, '_'},
4447 {"format", required_argument, 0, 's'},
4448 {"help", no_argument, 0, 'h'},
4449 {"java", no_argument, 0, 'j'},
4450 {"no-strip-underscores", no_argument, 0, 'n'},
4451 {"version", no_argument, 0, 'v'},
4452 {0, no_argument, 0, 0}
4455 /* More 'friendly' abort that prints the line and file.
4456 config.h can #define abort fancy_abort if you like that sort of thing. */
4458 void
4459 fancy_abort ()
4461 fatal ("Internal gcc abort.");
4465 static const char *
4466 standard_symbol_characters PARAMS ((void));
4468 static const char *
4469 hp_symbol_characters PARAMS ((void));
4471 /* Return the string of non-alnum characters that may occur
4472 as a valid symbol component, in the standard assembler symbol
4473 syntax. */
4475 static const char *
4476 standard_symbol_characters ()
4478 return "_$.";
4482 /* Return the string of non-alnum characters that may occur
4483 as a valid symbol name component in an HP object file.
4485 Note that, since HP's compiler generates object code straight from
4486 C++ source, without going through an assembler, its mangled
4487 identifiers can use all sorts of characters that no assembler would
4488 tolerate, so the alphabet this function creates is a little odd.
4489 Here are some sample mangled identifiers offered by HP:
4491 typeid*__XT24AddressIndExpClassMember_
4492 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4493 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4495 This still seems really weird to me, since nowhere else in this
4496 file is there anything to recognize curly brackets, parens, etc.
4497 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4498 this is right, but I still strongly suspect that there's a
4499 misunderstanding here.
4501 If we decide it's better for c++filt to use HP's assembler syntax
4502 to scrape identifiers out of its input, here's the definition of
4503 the symbol name syntax from the HP assembler manual:
4505 Symbols are composed of uppercase and lowercase letters, decimal
4506 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4507 underscore (_). A symbol can begin with a letter, digit underscore or
4508 dollar sign. If a symbol begins with a digit, it must contain a
4509 non-digit character.
4511 So have fun. */
4512 static const char *
4513 hp_symbol_characters ()
4515 return "_$.<>#,*&[]:(){}";
4519 extern int main PARAMS ((int, char **));
4522 main (argc, argv)
4523 int argc;
4524 char **argv;
4526 char *result;
4527 int c;
4528 const char *valid_symbols;
4530 program_name = argv[0];
4532 strip_underscore = prepends_underscore;
4534 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4536 switch (c)
4538 case '?':
4539 usage (stderr, 1);
4540 break;
4541 case 'h':
4542 usage (stdout, 0);
4543 case 'n':
4544 strip_underscore = 0;
4545 break;
4546 case 'v':
4547 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4548 return (0);
4549 case '_':
4550 strip_underscore = 1;
4551 break;
4552 case 'j':
4553 flags |= DMGL_JAVA;
4554 break;
4555 case 's':
4556 if (strcmp (optarg, "gnu") == 0)
4558 current_demangling_style = gnu_demangling;
4560 else if (strcmp (optarg, "lucid") == 0)
4562 current_demangling_style = lucid_demangling;
4564 else if (strcmp (optarg, "arm") == 0)
4566 current_demangling_style = arm_demangling;
4568 else if (strcmp (optarg, "hp") == 0)
4570 current_demangling_style = hp_demangling;
4572 else if (strcmp (optarg, "edg") == 0)
4574 current_demangling_style = edg_demangling;
4576 else
4578 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4579 program_name, optarg);
4580 return (1);
4582 break;
4586 if (optind < argc)
4588 for ( ; optind < argc; optind++)
4590 demangle_it (argv[optind]);
4593 else
4595 switch (current_demangling_style)
4597 case gnu_demangling:
4598 case lucid_demangling:
4599 case arm_demangling:
4600 case edg_demangling:
4601 valid_symbols = standard_symbol_characters ();
4602 break;
4603 case hp_demangling:
4604 valid_symbols = hp_symbol_characters ();
4605 break;
4606 default:
4607 /* Folks should explicitly indicate the appropriate alphabet for
4608 each demangling. Providing a default would allow the
4609 question to go unconsidered. */
4610 abort ();
4613 for (;;)
4615 int i = 0;
4616 c = getchar ();
4617 /* Try to read a label. */
4618 while (c != EOF && (isalnum (c) || strchr (valid_symbols, c)))
4620 if (i >= MBUF_SIZE-1)
4621 break;
4622 mbuffer[i++] = c;
4623 c = getchar ();
4625 if (i > 0)
4627 int skip_first = 0;
4629 if (mbuffer[0] == '.')
4630 ++skip_first;
4631 if (strip_underscore && mbuffer[skip_first] == '_')
4632 ++skip_first;
4634 if (skip_first > i)
4635 skip_first = i;
4637 mbuffer[i] = 0;
4639 result = cplus_demangle (mbuffer + skip_first, flags);
4640 if (result)
4642 if (mbuffer[0] == '.')
4643 putc ('.', stdout);
4644 fputs (result, stdout);
4645 free (result);
4647 else
4648 fputs (mbuffer, stdout);
4650 fflush (stdout);
4652 if (c == EOF)
4653 break;
4654 putchar (c);
4658 return (0);
4661 static void
4662 fatal (str)
4663 const char *str;
4665 fprintf (stderr, "%s: %s\n", program_name, str);
4666 exit (1);
4670 xmalloc (size)
4671 size_t size;
4673 register PTR value = (PTR) malloc (size);
4674 if (value == 0)
4675 fatal ("virtual memory exhausted");
4676 return value;
4680 xrealloc (ptr, size)
4681 PTR ptr;
4682 size_t size;
4684 register PTR value = (PTR) realloc (ptr, size);
4685 if (value == 0)
4686 fatal ("virtual memory exhausted");
4687 return value;
4689 #endif /* main */