* cplus-dem.c (INTBUF_SIZE): New macro.
[official-gcc.git] / libiberty / cplus-dem.c
blob7e8c74f6b13518a75f0cc06369961a9433ca4134
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 static const char *
454 standard_symbol_characters PARAMS ((void));
456 static const char *
457 hp_symbol_characters PARAMS ((void));
459 /* Translate count to integer, consuming tokens in the process.
460 Conversion terminates on the first non-digit character.
462 Trying to consume something that isn't a count results in no
463 consumption of input and a return of -1.
465 Overflow consumes the rest of the digits, and returns -1. */
467 static int
468 consume_count (type)
469 const char **type;
471 int count = 0;
473 if (! isdigit ((unsigned char)**type))
474 return -1;
476 while (isdigit ((unsigned char)**type))
478 count *= 10;
480 /* Check for overflow.
481 We assume that count is represented using two's-complement;
482 no power of two is divisible by ten, so if an overflow occurs
483 when multiplying by ten, the result will not be a multiple of
484 ten. */
485 if ((count % 10) != 0)
487 while (isdigit ((unsigned char) **type))
488 (*type)++;
489 return -1;
492 count += **type - '0';
493 (*type)++;
496 return (count);
500 /* Like consume_count, but for counts that are preceded and followed
501 by '_' if they are greater than 10. Also, -1 is returned for
502 failure, since 0 can be a valid value. */
504 static int
505 consume_count_with_underscores (mangled)
506 const char **mangled;
508 int idx;
510 if (**mangled == '_')
512 (*mangled)++;
513 if (!isdigit ((unsigned char)**mangled))
514 return -1;
516 idx = consume_count (mangled);
517 if (**mangled != '_')
518 /* The trailing underscore was missing. */
519 return -1;
521 (*mangled)++;
523 else
525 if (**mangled < '0' || **mangled > '9')
526 return -1;
528 idx = **mangled - '0';
529 (*mangled)++;
532 return idx;
535 /* C is the code for a type-qualifier. Return the TYPE_QUAL
536 corresponding to this qualifier. */
538 static int
539 code_for_qualifier (c)
540 int c;
542 switch (c)
544 case 'C':
545 return TYPE_QUAL_CONST;
547 case 'V':
548 return TYPE_QUAL_VOLATILE;
550 case 'u':
551 return TYPE_QUAL_RESTRICT;
553 default:
554 break;
557 /* C was an invalid qualifier. */
558 abort ();
561 /* Return the string corresponding to the qualifiers given by
562 TYPE_QUALS. */
564 static const char*
565 qualifier_string (type_quals)
566 int type_quals;
568 switch (type_quals)
570 case TYPE_UNQUALIFIED:
571 return "";
573 case TYPE_QUAL_CONST:
574 return "const";
576 case TYPE_QUAL_VOLATILE:
577 return "volatile";
579 case TYPE_QUAL_RESTRICT:
580 return "__restrict";
582 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
583 return "const volatile";
585 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
586 return "const __restrict";
588 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
589 return "volatile __restrict";
591 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
592 return "const volatile __restrict";
594 default:
595 break;
598 /* TYPE_QUALS was an invalid qualifier set. */
599 abort ();
602 /* C is the code for a type-qualifier. Return the string
603 corresponding to this qualifier. This function should only be
604 called with a valid qualifier code. */
606 static const char*
607 demangle_qualifier (c)
608 int c;
610 return qualifier_string (code_for_qualifier (c));
614 cplus_demangle_opname (opname, result, options)
615 const char *opname;
616 char *result;
617 int options;
619 int len, len1, ret;
620 string type;
621 struct work_stuff work[1];
622 const char *tem;
624 len = strlen(opname);
625 result[0] = '\0';
626 ret = 0;
627 memset ((char *) work, 0, sizeof (work));
628 work->options = options;
630 if (opname[0] == '_' && opname[1] == '_'
631 && opname[2] == 'o' && opname[3] == 'p')
633 /* ANSI. */
634 /* type conversion operator. */
635 tem = opname + 4;
636 if (do_type (work, &tem, &type))
638 strcat (result, "operator ");
639 strncat (result, type.b, type.p - type.b);
640 string_delete (&type);
641 ret = 1;
644 else if (opname[0] == '_' && opname[1] == '_'
645 && opname[2] >= 'a' && opname[2] <= 'z'
646 && opname[3] >= 'a' && opname[3] <= 'z')
648 if (opname[4] == '\0')
650 /* Operator. */
651 size_t i;
652 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
654 if (strlen (optable[i].in) == 2
655 && memcmp (optable[i].in, opname + 2, 2) == 0)
657 strcat (result, "operator");
658 strcat (result, optable[i].out);
659 ret = 1;
660 break;
664 else
666 if (opname[2] == 'a' && opname[5] == '\0')
668 /* Assignment. */
669 size_t i;
670 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
672 if (strlen (optable[i].in) == 3
673 && memcmp (optable[i].in, opname + 2, 3) == 0)
675 strcat (result, "operator");
676 strcat (result, optable[i].out);
677 ret = 1;
678 break;
684 else if (len >= 3
685 && opname[0] == 'o'
686 && opname[1] == 'p'
687 && strchr (cplus_markers, opname[2]) != NULL)
689 /* see if it's an assignment expression */
690 if (len >= 10 /* op$assign_ */
691 && memcmp (opname + 3, "assign_", 7) == 0)
693 size_t i;
694 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
696 len1 = len - 10;
697 if ((int) strlen (optable[i].in) == len1
698 && memcmp (optable[i].in, opname + 10, len1) == 0)
700 strcat (result, "operator");
701 strcat (result, optable[i].out);
702 strcat (result, "=");
703 ret = 1;
704 break;
708 else
710 size_t i;
711 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
713 len1 = len - 3;
714 if ((int) strlen (optable[i].in) == len1
715 && memcmp (optable[i].in, opname + 3, len1) == 0)
717 strcat (result, "operator");
718 strcat (result, optable[i].out);
719 ret = 1;
720 break;
725 else if (len >= 5 && memcmp (opname, "type", 4) == 0
726 && strchr (cplus_markers, opname[4]) != NULL)
728 /* type conversion operator */
729 tem = opname + 5;
730 if (do_type (work, &tem, &type))
732 strcat (result, "operator ");
733 strncat (result, type.b, type.p - type.b);
734 string_delete (&type);
735 ret = 1;
738 squangle_mop_up (work);
739 return ret;
742 /* Takes operator name as e.g. "++" and returns mangled
743 operator name (e.g. "postincrement_expr"), or NULL if not found.
745 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
746 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
748 const char *
749 cplus_mangle_opname (opname, options)
750 const char *opname;
751 int options;
753 size_t i;
754 int len;
756 len = strlen (opname);
757 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
759 if ((int) strlen (optable[i].out) == len
760 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
761 && memcmp (optable[i].out, opname, len) == 0)
762 return optable[i].in;
764 return (0);
767 /* char *cplus_demangle (const char *mangled, int options)
769 If MANGLED is a mangled function name produced by GNU C++, then
770 a pointer to a malloced string giving a C++ representation
771 of the name will be returned; otherwise NULL will be returned.
772 It is the caller's responsibility to free the string which
773 is returned.
775 The OPTIONS arg may contain one or more of the following bits:
777 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
778 included.
779 DMGL_PARAMS Function parameters are included.
781 For example,
783 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
784 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
785 cplus_demangle ("foo__1Ai", 0) => "A::foo"
787 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
788 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
789 cplus_demangle ("foo__1Afe", 0) => "A::foo"
791 Note that any leading underscores, or other such characters prepended by
792 the compilation system, are presumed to have already been stripped from
793 MANGLED. */
795 char *
796 cplus_demangle (mangled, options)
797 const char *mangled;
798 int options;
800 char *ret;
801 struct work_stuff work[1];
802 memset ((char *) work, 0, sizeof (work));
803 work -> options = options;
804 if ((work -> options & DMGL_STYLE_MASK) == 0)
805 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
807 ret = internal_cplus_demangle (work, mangled);
808 squangle_mop_up (work);
809 return (ret);
813 /* This function performs most of what cplus_demangle use to do, but
814 to be able to demangle a name with a B, K or n code, we need to
815 have a longer term memory of what types have been seen. The original
816 now intializes and cleans up the squangle code info, while internal
817 calls go directly to this routine to avoid resetting that info. */
819 static char *
820 internal_cplus_demangle (work, mangled)
821 struct work_stuff *work;
822 const char *mangled;
825 string decl;
826 int success = 0;
827 char *demangled = NULL;
828 int s1,s2,s3,s4;
829 s1 = work->constructor;
830 s2 = work->destructor;
831 s3 = work->static_type;
832 s4 = work->type_quals;
833 work->constructor = work->destructor = 0;
834 work->type_quals = TYPE_UNQUALIFIED;
835 work->dllimported = 0;
837 if ((mangled != NULL) && (*mangled != '\0'))
839 string_init (&decl);
841 /* First check to see if gnu style demangling is active and if the
842 string to be demangled contains a CPLUS_MARKER. If so, attempt to
843 recognize one of the gnu special forms rather than looking for a
844 standard prefix. In particular, don't worry about whether there
845 is a "__" string in the mangled string. Consider "_$_5__foo" for
846 example. */
848 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
850 success = gnu_special (work, &mangled, &decl);
852 if (!success)
854 success = demangle_prefix (work, &mangled, &decl);
856 if (success && (*mangled != '\0'))
858 success = demangle_signature (work, &mangled, &decl);
860 if (work->constructor == 2)
862 string_prepend (&decl, "global constructors keyed to ");
863 work->constructor = 0;
865 else if (work->destructor == 2)
867 string_prepend (&decl, "global destructors keyed to ");
868 work->destructor = 0;
870 else if (work->dllimported == 1)
872 string_prepend (&decl, "import stub for ");
873 work->dllimported = 0;
875 demangled = mop_up (work, &decl, success);
877 work->constructor = s1;
878 work->destructor = s2;
879 work->static_type = s3;
880 work->type_quals = s4;
881 return (demangled);
885 /* Clear out and squangling related storage */
886 static void
887 squangle_mop_up (work)
888 struct work_stuff *work;
890 /* clean up the B and K type mangling types. */
891 forget_B_and_K_types (work);
892 if (work -> btypevec != NULL)
894 free ((char *) work -> btypevec);
896 if (work -> ktypevec != NULL)
898 free ((char *) work -> ktypevec);
902 /* Clear out any mangled storage */
904 static char *
905 mop_up (work, declp, success)
906 struct work_stuff *work;
907 string *declp;
908 int success;
910 char *demangled = NULL;
912 /* Discard the remembered types, if any. */
914 forget_types (work);
915 if (work -> typevec != NULL)
917 free ((char *) work -> typevec);
918 work -> typevec = NULL;
919 work -> typevec_size = 0;
921 if (work->tmpl_argvec)
923 int i;
925 for (i = 0; i < work->ntmpl_args; i++)
926 if (work->tmpl_argvec[i])
927 free ((char*) work->tmpl_argvec[i]);
929 free ((char*) work->tmpl_argvec);
930 work->tmpl_argvec = NULL;
932 if (work->previous_argument)
934 string_delete (work->previous_argument);
935 free ((char*) work->previous_argument);
936 work->previous_argument = NULL;
939 /* If demangling was successful, ensure that the demangled string is null
940 terminated and return it. Otherwise, free the demangling decl. */
942 if (!success)
944 string_delete (declp);
946 else
948 string_appendn (declp, "", 1);
949 demangled = declp -> b;
951 return (demangled);
956 LOCAL FUNCTION
958 demangle_signature -- demangle the signature part of a mangled name
960 SYNOPSIS
962 static int
963 demangle_signature (struct work_stuff *work, const char **mangled,
964 string *declp);
966 DESCRIPTION
968 Consume and demangle the signature portion of the mangled name.
970 DECLP is the string where demangled output is being built. At
971 entry it contains the demangled root name from the mangled name
972 prefix. I.E. either a demangled operator name or the root function
973 name. In some special cases, it may contain nothing.
975 *MANGLED points to the current unconsumed location in the mangled
976 name. As tokens are consumed and demangling is performed, the
977 pointer is updated to continuously point at the next token to
978 be consumed.
980 Demangling GNU style mangled names is nasty because there is no
981 explicit token that marks the start of the outermost function
982 argument list. */
984 static int
985 demangle_signature (work, mangled, declp)
986 struct work_stuff *work;
987 const char **mangled;
988 string *declp;
990 int success = 1;
991 int func_done = 0;
992 int expect_func = 0;
993 int expect_return_type = 0;
994 const char *oldmangled = NULL;
995 string trawname;
996 string tname;
998 while (success && (**mangled != '\0'))
1000 switch (**mangled)
1002 case 'Q':
1003 oldmangled = *mangled;
1004 success = demangle_qualified (work, mangled, declp, 1, 0);
1005 if (success)
1006 remember_type (work, oldmangled, *mangled - oldmangled);
1007 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1008 expect_func = 1;
1009 oldmangled = NULL;
1010 break;
1012 case 'K':
1013 oldmangled = *mangled;
1014 success = demangle_qualified (work, mangled, declp, 1, 0);
1015 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1017 expect_func = 1;
1019 oldmangled = NULL;
1020 break;
1022 case 'S':
1023 /* Static member function */
1024 if (oldmangled == NULL)
1026 oldmangled = *mangled;
1028 (*mangled)++;
1029 work -> static_type = 1;
1030 break;
1032 case 'C':
1033 case 'V':
1034 case 'u':
1035 work->type_quals |= code_for_qualifier (**mangled);
1037 /* a qualified member function */
1038 if (oldmangled == NULL)
1039 oldmangled = *mangled;
1040 (*mangled)++;
1041 break;
1043 case 'L':
1044 /* Local class name follows after "Lnnn_" */
1045 if (HP_DEMANGLING)
1047 while (**mangled && (**mangled != '_'))
1048 (*mangled)++;
1049 if (!**mangled)
1050 success = 0;
1051 else
1052 (*mangled)++;
1054 else
1055 success = 0;
1056 break;
1058 case '0': case '1': case '2': case '3': case '4':
1059 case '5': case '6': case '7': case '8': case '9':
1060 if (oldmangled == NULL)
1062 oldmangled = *mangled;
1064 work->temp_start = -1; /* uppermost call to demangle_class */
1065 success = demangle_class (work, mangled, declp);
1066 if (success)
1068 remember_type (work, oldmangled, *mangled - oldmangled);
1070 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1072 /* EDG and others will have the "F", so we let the loop cycle
1073 if we are looking at one. */
1074 if (**mangled != 'F')
1075 expect_func = 1;
1077 oldmangled = NULL;
1078 break;
1080 case 'B':
1082 string s;
1083 success = do_type (work, mangled, &s);
1084 if (success)
1086 string_append (&s, SCOPE_STRING (work));
1087 string_prepends (declp, &s);
1089 oldmangled = NULL;
1090 expect_func = 1;
1092 break;
1094 case 'F':
1095 /* Function */
1096 /* ARM/HP style demangling includes a specific 'F' character after
1097 the class name. For GNU style, it is just implied. So we can
1098 safely just consume any 'F' at this point and be compatible
1099 with either style. */
1101 oldmangled = NULL;
1102 func_done = 1;
1103 (*mangled)++;
1105 /* For lucid/ARM/HP style we have to forget any types we might
1106 have remembered up to this point, since they were not argument
1107 types. GNU style considers all types seen as available for
1108 back references. See comment in demangle_args() */
1110 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1112 forget_types (work);
1114 success = demangle_args (work, mangled, declp);
1115 /* After picking off the function args, we expect to either
1116 find the function return type (preceded by an '_') or the
1117 end of the string. */
1118 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1120 ++(*mangled);
1121 /* At this level, we do not care about the return type. */
1122 success = do_type (work, mangled, &tname);
1123 string_delete (&tname);
1126 break;
1128 case 't':
1129 /* G++ Template */
1130 string_init(&trawname);
1131 string_init(&tname);
1132 if (oldmangled == NULL)
1134 oldmangled = *mangled;
1136 success = demangle_template (work, mangled, &tname,
1137 &trawname, 1, 1);
1138 if (success)
1140 remember_type (work, oldmangled, *mangled - oldmangled);
1142 string_append (&tname, SCOPE_STRING (work));
1144 string_prepends(declp, &tname);
1145 if (work -> destructor & 1)
1147 string_prepend (&trawname, "~");
1148 string_appends (declp, &trawname);
1149 work->destructor -= 1;
1151 if ((work->constructor & 1) || (work->destructor & 1))
1153 string_appends (declp, &trawname);
1154 work->constructor -= 1;
1156 string_delete(&trawname);
1157 string_delete(&tname);
1158 oldmangled = NULL;
1159 expect_func = 1;
1160 break;
1162 case '_':
1163 if (GNU_DEMANGLING && expect_return_type)
1165 /* Read the return type. */
1166 string return_type;
1167 string_init (&return_type);
1169 (*mangled)++;
1170 success = do_type (work, mangled, &return_type);
1171 APPEND_BLANK (&return_type);
1173 string_prepends (declp, &return_type);
1174 string_delete (&return_type);
1175 break;
1177 else
1178 /* At the outermost level, we cannot have a return type specified,
1179 so if we run into another '_' at this point we are dealing with
1180 a mangled name that is either bogus, or has been mangled by
1181 some algorithm we don't know how to deal with. So just
1182 reject the entire demangling. */
1183 /* However, "_nnn" is an expected suffix for alternate entry point
1184 numbered nnn for a function, with HP aCC, so skip over that
1185 without reporting failure. pai/1997-09-04 */
1186 if (HP_DEMANGLING)
1188 (*mangled)++;
1189 while (**mangled && isdigit ((unsigned char)**mangled))
1190 (*mangled)++;
1192 else
1193 success = 0;
1194 break;
1196 case 'H':
1197 if (GNU_DEMANGLING)
1199 /* A G++ template function. Read the template arguments. */
1200 success = demangle_template (work, mangled, declp, 0, 0,
1202 if (!(work->constructor & 1))
1203 expect_return_type = 1;
1204 (*mangled)++;
1205 break;
1207 else
1208 /* fall through */
1211 default:
1212 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1214 /* Assume we have stumbled onto the first outermost function
1215 argument token, and start processing args. */
1216 func_done = 1;
1217 success = demangle_args (work, mangled, declp);
1219 else
1221 /* Non-GNU demanglers use a specific token to mark the start
1222 of the outermost function argument tokens. Typically 'F',
1223 for ARM/HP-demangling, for example. So if we find something
1224 we are not prepared for, it must be an error. */
1225 success = 0;
1227 break;
1230 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1233 if (success && expect_func)
1235 func_done = 1;
1236 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1238 forget_types (work);
1240 success = demangle_args (work, mangled, declp);
1241 /* Since template include the mangling of their return types,
1242 we must set expect_func to 0 so that we don't try do
1243 demangle more arguments the next time we get here. */
1244 expect_func = 0;
1248 if (success && !func_done)
1250 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1252 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1253 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1254 first case, and need to ensure that the '(void)' gets added to
1255 the current declp. Note that with ARM/HP, the first case
1256 represents the name of a static data member 'foo::bar',
1257 which is in the current declp, so we leave it alone. */
1258 success = demangle_args (work, mangled, declp);
1261 if (success && PRINT_ARG_TYPES)
1263 if (work->static_type)
1264 string_append (declp, " static");
1265 if (work->type_quals != TYPE_UNQUALIFIED)
1267 APPEND_BLANK (declp);
1268 string_append (declp, qualifier_string (work->type_quals));
1272 return (success);
1275 #if 0
1277 static int
1278 demangle_method_args (work, mangled, declp)
1279 struct work_stuff *work;
1280 const char **mangled;
1281 string *declp;
1283 int success = 0;
1285 if (work -> static_type)
1287 string_append (declp, *mangled + 1);
1288 *mangled += strlen (*mangled);
1289 success = 1;
1291 else
1293 success = demangle_args (work, mangled, declp);
1295 return (success);
1298 #endif
1300 static int
1301 demangle_template_template_parm (work, mangled, tname)
1302 struct work_stuff *work;
1303 const char **mangled;
1304 string *tname;
1306 int i;
1307 int r;
1308 int need_comma = 0;
1309 int success = 1;
1310 string temp;
1312 string_append (tname, "template <");
1313 /* get size of template parameter list */
1314 if (get_count (mangled, &r))
1316 for (i = 0; i < r; i++)
1318 if (need_comma)
1320 string_append (tname, ", ");
1323 /* Z for type parameters */
1324 if (**mangled == 'Z')
1326 (*mangled)++;
1327 string_append (tname, "class");
1329 /* z for template parameters */
1330 else if (**mangled == 'z')
1332 (*mangled)++;
1333 success =
1334 demangle_template_template_parm (work, mangled, tname);
1335 if (!success)
1337 break;
1340 else
1342 /* temp is initialized in do_type */
1343 success = do_type (work, mangled, &temp);
1344 if (success)
1346 string_appends (tname, &temp);
1348 string_delete(&temp);
1349 if (!success)
1351 break;
1354 need_comma = 1;
1358 if (tname->p[-1] == '>')
1359 string_append (tname, " ");
1360 string_append (tname, "> class");
1361 return (success);
1364 static int
1365 demangle_expression (work, mangled, s, tk)
1366 struct work_stuff *work;
1367 const char** mangled;
1368 string* s;
1369 type_kind_t tk;
1371 int need_operator = 0;
1372 int success;
1374 success = 1;
1375 string_appendn (s, "(", 1);
1376 (*mangled)++;
1377 while (success && **mangled != 'W' && **mangled != '\0')
1379 if (need_operator)
1381 size_t i;
1382 size_t len;
1384 success = 0;
1386 len = strlen (*mangled);
1388 for (i = 0;
1389 i < sizeof (optable) / sizeof (optable [0]);
1390 ++i)
1392 size_t l = strlen (optable[i].in);
1394 if (l <= len
1395 && memcmp (optable[i].in, *mangled, l) == 0)
1397 string_appendn (s, " ", 1);
1398 string_append (s, optable[i].out);
1399 string_appendn (s, " ", 1);
1400 success = 1;
1401 (*mangled) += l;
1402 break;
1406 if (!success)
1407 break;
1409 else
1410 need_operator = 1;
1412 success = demangle_template_value_parm (work, mangled, s, tk);
1415 if (**mangled != 'W')
1416 success = 0;
1417 else
1419 string_appendn (s, ")", 1);
1420 (*mangled)++;
1423 return success;
1426 static int
1427 demangle_integral_value (work, mangled, s)
1428 struct work_stuff *work;
1429 const char** mangled;
1430 string* s;
1432 int success;
1434 if (**mangled == 'E')
1435 success = demangle_expression (work, mangled, s, tk_integral);
1436 else if (**mangled == 'Q' || **mangled == 'K')
1437 success = demangle_qualified (work, mangled, s, 0, 1);
1438 else
1440 int value;
1442 success = 0;
1444 /* Negative numbers are indicated with a leading `m'. */
1445 if (**mangled == 'm')
1447 string_appendn (s, "-", 1);
1448 (*mangled)++;
1451 /* Read the rest of the number. */
1452 value = consume_count_with_underscores (mangled);
1453 if (value != -1)
1455 char buf[INTBUF_SIZE];
1456 sprintf (buf, "%d", value);
1457 string_append (s, buf);
1459 /* If the next character is an underscore, skip it. */
1460 if (**mangled == '_')
1461 (*mangled)++;
1463 /* All is well. */
1464 success = 1;
1468 return success;
1471 /* Demangle the real value in MANGLED. */
1473 static int
1474 demangle_real_value (work, mangled, s)
1475 struct work_stuff *work;
1476 const char **mangled;
1477 string* s;
1479 if (**mangled == 'E')
1480 return demangle_expression (work, mangled, s, tk_real);
1482 if (**mangled == 'm')
1484 string_appendn (s, "-", 1);
1485 (*mangled)++;
1487 while (isdigit ((unsigned char)**mangled))
1489 string_appendn (s, *mangled, 1);
1490 (*mangled)++;
1492 if (**mangled == '.') /* fraction */
1494 string_appendn (s, ".", 1);
1495 (*mangled)++;
1496 while (isdigit ((unsigned char)**mangled))
1498 string_appendn (s, *mangled, 1);
1499 (*mangled)++;
1502 if (**mangled == 'e') /* exponent */
1504 string_appendn (s, "e", 1);
1505 (*mangled)++;
1506 while (isdigit ((unsigned char)**mangled))
1508 string_appendn (s, *mangled, 1);
1509 (*mangled)++;
1513 return 1;
1516 static int
1517 demangle_template_value_parm (work, mangled, s, tk)
1518 struct work_stuff *work;
1519 const char **mangled;
1520 string* s;
1521 type_kind_t tk;
1523 int success = 1;
1525 if (**mangled == 'Y')
1527 /* The next argument is a template parameter. */
1528 int idx;
1530 (*mangled)++;
1531 idx = consume_count_with_underscores (mangled);
1532 if (idx == -1
1533 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1534 || consume_count_with_underscores (mangled) == -1)
1535 return -1;
1536 if (work->tmpl_argvec)
1537 string_append (s, work->tmpl_argvec[idx]);
1538 else
1539 string_append_template_idx (s, idx);
1541 else if (tk == tk_integral)
1542 success = demangle_integral_value (work, mangled, s);
1543 else if (tk == tk_char)
1545 char tmp[2];
1546 int val;
1547 if (**mangled == 'm')
1549 string_appendn (s, "-", 1);
1550 (*mangled)++;
1552 string_appendn (s, "'", 1);
1553 val = consume_count(mangled);
1554 if (val <= 0)
1555 success = 0;
1556 else
1558 tmp[0] = (char)val;
1559 tmp[1] = '\0';
1560 string_appendn (s, &tmp[0], 1);
1561 string_appendn (s, "'", 1);
1564 else if (tk == tk_bool)
1566 int val = consume_count (mangled);
1567 if (val == 0)
1568 string_appendn (s, "false", 5);
1569 else if (val == 1)
1570 string_appendn (s, "true", 4);
1571 else
1572 success = 0;
1574 else if (tk == tk_real)
1575 success = demangle_real_value (work, mangled, s);
1576 else if (tk == tk_pointer || tk == tk_reference)
1578 if (**mangled == 'Q')
1579 success = demangle_qualified (work, mangled, s,
1580 /*isfuncname=*/0,
1581 /*append=*/1);
1582 else
1584 int symbol_len = consume_count (mangled);
1585 if (symbol_len == -1)
1586 return -1;
1587 if (symbol_len == 0)
1588 string_appendn (s, "0", 1);
1589 else
1591 char *p = xmalloc (symbol_len + 1), *q;
1592 strncpy (p, *mangled, symbol_len);
1593 p [symbol_len] = '\0';
1594 /* We use cplus_demangle here, rather than
1595 internal_cplus_demangle, because the name of the entity
1596 mangled here does not make use of any of the squangling
1597 or type-code information we have built up thus far; it is
1598 mangled independently. */
1599 q = cplus_demangle (p, work->options);
1600 if (tk == tk_pointer)
1601 string_appendn (s, "&", 1);
1602 /* FIXME: Pointer-to-member constants should get a
1603 qualifying class name here. */
1604 if (q)
1606 string_append (s, q);
1607 free (q);
1609 else
1610 string_append (s, p);
1611 free (p);
1613 *mangled += symbol_len;
1617 return success;
1620 /* Demangle the template name in MANGLED. The full name of the
1621 template (e.g., S<int>) is placed in TNAME. The name without the
1622 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1623 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1624 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1625 the tmeplate is remembered in the list of back-referenceable
1626 types. */
1628 static int
1629 demangle_template (work, mangled, tname, trawname, is_type, remember)
1630 struct work_stuff *work;
1631 const char **mangled;
1632 string *tname;
1633 string *trawname;
1634 int is_type;
1635 int remember;
1637 int i;
1638 int r;
1639 int need_comma = 0;
1640 int success = 0;
1641 const char *start;
1642 int is_java_array = 0;
1643 string temp;
1644 int bindex = 0;
1646 (*mangled)++;
1647 if (is_type)
1649 if (remember)
1650 bindex = register_Btype (work);
1651 start = *mangled;
1652 /* get template name */
1653 if (**mangled == 'z')
1655 int idx;
1656 (*mangled)++;
1657 (*mangled)++;
1659 idx = consume_count_with_underscores (mangled);
1660 if (idx == -1
1661 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1662 || consume_count_with_underscores (mangled) == -1)
1663 return (0);
1665 if (work->tmpl_argvec)
1667 string_append (tname, work->tmpl_argvec[idx]);
1668 if (trawname)
1669 string_append (trawname, work->tmpl_argvec[idx]);
1671 else
1673 string_append_template_idx (tname, idx);
1674 if (trawname)
1675 string_append_template_idx (trawname, idx);
1678 else
1680 if ((r = consume_count (mangled)) <= 0
1681 || (int) strlen (*mangled) < r)
1683 return (0);
1685 is_java_array = (work -> options & DMGL_JAVA)
1686 && strncmp (*mangled, "JArray1Z", 8) == 0;
1687 if (! is_java_array)
1689 string_appendn (tname, *mangled, r);
1691 if (trawname)
1692 string_appendn (trawname, *mangled, r);
1693 *mangled += r;
1696 if (!is_java_array)
1697 string_append (tname, "<");
1698 /* get size of template parameter list */
1699 if (!get_count (mangled, &r))
1701 return (0);
1703 if (!is_type)
1705 /* Create an array for saving the template argument values. */
1706 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1707 work->ntmpl_args = r;
1708 for (i = 0; i < r; i++)
1709 work->tmpl_argvec[i] = 0;
1711 for (i = 0; i < r; i++)
1713 if (need_comma)
1715 string_append (tname, ", ");
1717 /* Z for type parameters */
1718 if (**mangled == 'Z')
1720 (*mangled)++;
1721 /* temp is initialized in do_type */
1722 success = do_type (work, mangled, &temp);
1723 if (success)
1725 string_appends (tname, &temp);
1727 if (!is_type)
1729 /* Save the template argument. */
1730 int len = temp.p - temp.b;
1731 work->tmpl_argvec[i] = xmalloc (len + 1);
1732 memcpy (work->tmpl_argvec[i], temp.b, len);
1733 work->tmpl_argvec[i][len] = '\0';
1736 string_delete(&temp);
1737 if (!success)
1739 break;
1742 /* z for template parameters */
1743 else if (**mangled == 'z')
1745 int r2;
1746 (*mangled)++;
1747 success = demangle_template_template_parm (work, mangled, tname);
1749 if (success
1750 && (r2 = consume_count (mangled)) > 0
1751 && (int) strlen (*mangled) >= r2)
1753 string_append (tname, " ");
1754 string_appendn (tname, *mangled, r2);
1755 if (!is_type)
1757 /* Save the template argument. */
1758 int len = r2;
1759 work->tmpl_argvec[i] = xmalloc (len + 1);
1760 memcpy (work->tmpl_argvec[i], *mangled, len);
1761 work->tmpl_argvec[i][len] = '\0';
1763 *mangled += r2;
1765 if (!success)
1767 break;
1770 else
1772 string param;
1773 string* s;
1775 /* otherwise, value parameter */
1777 /* temp is initialized in do_type */
1778 success = do_type (work, mangled, &temp);
1779 string_delete(&temp);
1780 if (!success)
1781 break;
1783 if (!is_type)
1785 s = &param;
1786 string_init (s);
1788 else
1789 s = tname;
1791 success = demangle_template_value_parm (work, mangled, s,
1792 (type_kind_t) success);
1794 if (!success)
1796 if (!is_type)
1797 string_delete (s);
1798 success = 0;
1799 break;
1802 if (!is_type)
1804 int len = s->p - s->b;
1805 work->tmpl_argvec[i] = xmalloc (len + 1);
1806 memcpy (work->tmpl_argvec[i], s->b, len);
1807 work->tmpl_argvec[i][len] = '\0';
1809 string_appends (tname, s);
1810 string_delete (s);
1813 need_comma = 1;
1815 if (is_java_array)
1817 string_append (tname, "[]");
1819 else
1821 if (tname->p[-1] == '>')
1822 string_append (tname, " ");
1823 string_append (tname, ">");
1826 if (is_type && remember)
1827 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1830 if (work -> static_type)
1832 string_append (declp, *mangled + 1);
1833 *mangled += strlen (*mangled);
1834 success = 1;
1836 else
1838 success = demangle_args (work, mangled, declp);
1842 return (success);
1845 static int
1846 arm_pt (work, mangled, n, anchor, args)
1847 struct work_stuff *work;
1848 const char *mangled;
1849 int n;
1850 const char **anchor, **args;
1852 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1853 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1854 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1856 int len;
1857 *args = *anchor + 6;
1858 len = consume_count (args);
1859 if (len == -1)
1860 return 0;
1861 if (*args + len == mangled + n && **args == '_')
1863 ++*args;
1864 return 1;
1867 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1869 if ((*anchor = mystrstr (mangled, "__tm__"))
1870 || (*anchor = mystrstr (mangled, "__ps__"))
1871 || (*anchor = mystrstr (mangled, "__pt__")))
1873 int len;
1874 *args = *anchor + 6;
1875 len = consume_count (args);
1876 if (len == -1)
1877 return 0;
1878 if (*args + len == mangled + n && **args == '_')
1880 ++*args;
1881 return 1;
1884 else if ((*anchor = mystrstr (mangled, "__S")))
1886 int len;
1887 *args = *anchor + 3;
1888 len = consume_count (args);
1889 if (len == -1)
1890 return 0;
1891 if (*args + len == mangled + n && **args == '_')
1893 ++*args;
1894 return 1;
1899 return 0;
1902 static void
1903 demangle_arm_hp_template (work, mangled, n, declp)
1904 struct work_stuff *work;
1905 const char **mangled;
1906 int n;
1907 string *declp;
1909 const char *p;
1910 const char *args;
1911 const char *e = *mangled + n;
1912 string arg;
1914 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1915 template args */
1916 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1918 char *start_spec_args = NULL;
1920 /* First check for and omit template specialization pseudo-arguments,
1921 such as in "Spec<#1,#1.*>" */
1922 start_spec_args = strchr (*mangled, '<');
1923 if (start_spec_args && (start_spec_args - *mangled < n))
1924 string_appendn (declp, *mangled, start_spec_args - *mangled);
1925 else
1926 string_appendn (declp, *mangled, n);
1927 (*mangled) += n + 1;
1928 string_init (&arg);
1929 if (work->temp_start == -1) /* non-recursive call */
1930 work->temp_start = declp->p - declp->b;
1931 string_append (declp, "<");
1932 while (1)
1934 string_clear (&arg);
1935 switch (**mangled)
1937 case 'T':
1938 /* 'T' signals a type parameter */
1939 (*mangled)++;
1940 if (!do_type (work, mangled, &arg))
1941 goto hpacc_template_args_done;
1942 break;
1944 case 'U':
1945 case 'S':
1946 /* 'U' or 'S' signals an integral value */
1947 if (!do_hpacc_template_const_value (work, mangled, &arg))
1948 goto hpacc_template_args_done;
1949 break;
1951 case 'A':
1952 /* 'A' signals a named constant expression (literal) */
1953 if (!do_hpacc_template_literal (work, mangled, &arg))
1954 goto hpacc_template_args_done;
1955 break;
1957 default:
1958 /* Today, 1997-09-03, we have only the above types
1959 of template parameters */
1960 /* FIXME: maybe this should fail and return null */
1961 goto hpacc_template_args_done;
1963 string_appends (declp, &arg);
1964 /* Check if we're at the end of template args.
1965 0 if at end of static member of template class,
1966 _ if done with template args for a function */
1967 if ((**mangled == '\000') || (**mangled == '_'))
1968 break;
1969 else
1970 string_append (declp, ",");
1972 hpacc_template_args_done:
1973 string_append (declp, ">");
1974 string_delete (&arg);
1975 if (**mangled == '_')
1976 (*mangled)++;
1977 return;
1979 /* ARM template? (Also handles HP cfront extensions) */
1980 else if (arm_pt (work, *mangled, n, &p, &args))
1982 string type_str;
1984 string_init (&arg);
1985 string_appendn (declp, *mangled, p - *mangled);
1986 if (work->temp_start == -1) /* non-recursive call */
1987 work->temp_start = declp->p - declp->b;
1988 string_append (declp, "<");
1989 /* should do error checking here */
1990 while (args < e) {
1991 string_clear (&arg);
1993 /* Check for type or literal here */
1994 switch (*args)
1996 /* HP cfront extensions to ARM for template args */
1997 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1998 /* FIXME: We handle only numeric literals for HP cfront */
1999 case 'X':
2000 /* A typed constant value follows */
2001 args++;
2002 if (!do_type (work, &args, &type_str))
2003 goto cfront_template_args_done;
2004 string_append (&arg, "(");
2005 string_appends (&arg, &type_str);
2006 string_append (&arg, ")");
2007 if (*args != 'L')
2008 goto cfront_template_args_done;
2009 args++;
2010 /* Now snarf a literal value following 'L' */
2011 if (!snarf_numeric_literal (&args, &arg))
2012 goto cfront_template_args_done;
2013 break;
2015 case 'L':
2016 /* Snarf a literal following 'L' */
2017 args++;
2018 if (!snarf_numeric_literal (&args, &arg))
2019 goto cfront_template_args_done;
2020 break;
2021 default:
2022 /* Not handling other HP cfront stuff */
2023 if (!do_type (work, &args, &arg))
2024 goto cfront_template_args_done;
2026 string_appends (declp, &arg);
2027 string_append (declp, ",");
2029 cfront_template_args_done:
2030 string_delete (&arg);
2031 if (args >= e)
2032 --declp->p; /* remove extra comma */
2033 string_append (declp, ">");
2035 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2036 && (*mangled)[9] == 'N'
2037 && (*mangled)[8] == (*mangled)[10]
2038 && strchr (cplus_markers, (*mangled)[8]))
2040 /* A member of the anonymous namespace. */
2041 string_append (declp, "{anonymous}");
2043 else
2045 if (work->temp_start == -1) /* non-recursive call only */
2046 work->temp_start = 0; /* disable in recursive calls */
2047 string_appendn (declp, *mangled, n);
2049 *mangled += n;
2052 /* Extract a class name, possibly a template with arguments, from the
2053 mangled string; qualifiers, local class indicators, etc. have
2054 already been dealt with */
2056 static int
2057 demangle_class_name (work, mangled, declp)
2058 struct work_stuff *work;
2059 const char **mangled;
2060 string *declp;
2062 int n;
2063 int success = 0;
2065 n = consume_count (mangled);
2066 if (n == -1)
2067 return 0;
2068 if ((int) strlen (*mangled) >= n)
2070 demangle_arm_hp_template (work, mangled, n, declp);
2071 success = 1;
2074 return (success);
2079 LOCAL FUNCTION
2081 demangle_class -- demangle a mangled class sequence
2083 SYNOPSIS
2085 static int
2086 demangle_class (struct work_stuff *work, const char **mangled,
2087 strint *declp)
2089 DESCRIPTION
2091 DECLP points to the buffer into which demangling is being done.
2093 *MANGLED points to the current token to be demangled. On input,
2094 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2095 On exit, it points to the next token after the mangled class on
2096 success, or the first unconsumed token on failure.
2098 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2099 we are demangling a constructor or destructor. In this case
2100 we prepend "class::class" or "class::~class" to DECLP.
2102 Otherwise, we prepend "class::" to the current DECLP.
2104 Reset the constructor/destructor flags once they have been
2105 "consumed". This allows demangle_class to be called later during
2106 the same demangling, to do normal class demangling.
2108 Returns 1 if demangling is successful, 0 otherwise.
2112 static int
2113 demangle_class (work, mangled, declp)
2114 struct work_stuff *work;
2115 const char **mangled;
2116 string *declp;
2118 int success = 0;
2119 int btype;
2120 string class_name;
2121 char *save_class_name_end = 0;
2123 string_init (&class_name);
2124 btype = register_Btype (work);
2125 if (demangle_class_name (work, mangled, &class_name))
2127 save_class_name_end = class_name.p;
2128 if ((work->constructor & 1) || (work->destructor & 1))
2130 /* adjust so we don't include template args */
2131 if (work->temp_start && (work->temp_start != -1))
2133 class_name.p = class_name.b + work->temp_start;
2135 string_prepends (declp, &class_name);
2136 if (work -> destructor & 1)
2138 string_prepend (declp, "~");
2139 work -> destructor -= 1;
2141 else
2143 work -> constructor -= 1;
2146 class_name.p = save_class_name_end;
2147 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2148 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2149 string_prepend (declp, SCOPE_STRING (work));
2150 string_prepends (declp, &class_name);
2151 success = 1;
2153 string_delete (&class_name);
2154 return (success);
2159 LOCAL FUNCTION
2161 demangle_prefix -- consume the mangled name prefix and find signature
2163 SYNOPSIS
2165 static int
2166 demangle_prefix (struct work_stuff *work, const char **mangled,
2167 string *declp);
2169 DESCRIPTION
2171 Consume and demangle the prefix of the mangled name.
2173 DECLP points to the string buffer into which demangled output is
2174 placed. On entry, the buffer is empty. On exit it contains
2175 the root function name, the demangled operator name, or in some
2176 special cases either nothing or the completely demangled result.
2178 MANGLED points to the current pointer into the mangled name. As each
2179 token of the mangled name is consumed, it is updated. Upon entry
2180 the current mangled name pointer points to the first character of
2181 the mangled name. Upon exit, it should point to the first character
2182 of the signature if demangling was successful, or to the first
2183 unconsumed character if demangling of the prefix was unsuccessful.
2185 Returns 1 on success, 0 otherwise.
2188 static int
2189 demangle_prefix (work, mangled, declp)
2190 struct work_stuff *work;
2191 const char **mangled;
2192 string *declp;
2194 int success = 1;
2195 const char *scan;
2196 int i;
2198 if (strlen(*mangled) > 6
2199 && (strncmp(*mangled, "_imp__", 6) == 0
2200 || strncmp(*mangled, "__imp_", 6) == 0))
2202 /* it's a symbol imported from a PE dynamic library. Check for both
2203 new style prefix _imp__ and legacy __imp_ used by older versions
2204 of dlltool. */
2205 (*mangled) += 6;
2206 work->dllimported = 1;
2208 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2210 char *marker = strchr (cplus_markers, (*mangled)[8]);
2211 if (marker != NULL && *marker == (*mangled)[10])
2213 if ((*mangled)[9] == 'D')
2215 /* it's a GNU global destructor to be executed at program exit */
2216 (*mangled) += 11;
2217 work->destructor = 2;
2218 if (gnu_special (work, mangled, declp))
2219 return success;
2221 else if ((*mangled)[9] == 'I')
2223 /* it's a GNU global constructor to be executed at program init */
2224 (*mangled) += 11;
2225 work->constructor = 2;
2226 if (gnu_special (work, mangled, declp))
2227 return success;
2231 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2233 /* it's a ARM global destructor to be executed at program exit */
2234 (*mangled) += 7;
2235 work->destructor = 2;
2237 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2239 /* it's a ARM global constructor to be executed at program initial */
2240 (*mangled) += 7;
2241 work->constructor = 2;
2244 /* This block of code is a reduction in strength time optimization
2246 scan = mystrstr (*mangled, "__"); */
2249 scan = *mangled;
2251 do {
2252 scan = strchr (scan, '_');
2253 } while (scan != NULL && *++scan != '_');
2255 if (scan != NULL) --scan;
2258 if (scan != NULL)
2260 /* We found a sequence of two or more '_', ensure that we start at
2261 the last pair in the sequence. */
2262 i = strspn (scan, "_");
2263 if (i > 2)
2265 scan += (i - 2);
2269 if (scan == NULL)
2271 success = 0;
2273 else if (work -> static_type)
2275 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2277 success = 0;
2280 else if ((scan == *mangled)
2281 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2282 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2284 /* The ARM says nothing about the mangling of local variables.
2285 But cfront mangles local variables by prepending __<nesting_level>
2286 to them. As an extension to ARM demangling we handle this case. */
2287 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2288 && isdigit ((unsigned char)scan[2]))
2290 *mangled = scan + 2;
2291 consume_count (mangled);
2292 string_append (declp, *mangled);
2293 *mangled += strlen (*mangled);
2294 success = 1;
2296 else
2298 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2299 names like __Q2_3foo3bar for nested type names. So don't accept
2300 this style of constructor for cfront demangling. A GNU
2301 style member-template constructor starts with 'H'. */
2302 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2303 work -> constructor += 1;
2304 *mangled = scan + 2;
2307 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2309 /* Cfront-style parameterized type. Handled later as a signature. */
2310 success = 1;
2312 /* ARM template? */
2313 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2315 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2316 || (scan[2] == 'p' && scan[3] == 's')
2317 || (scan[2] == 'p' && scan[3] == 't')))
2319 /* EDG-style parameterized type. Handled later as a signature. */
2320 success = 1;
2322 /* EDG template? */
2323 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2325 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2326 && (scan[2] != 't'))
2328 /* Mangled name starts with "__". Skip over any leading '_' characters,
2329 then find the next "__" that separates the prefix from the signature.
2331 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2332 || (arm_special (mangled, declp) == 0))
2334 while (*scan == '_')
2336 scan++;
2338 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2340 /* No separator (I.E. "__not_mangled"), or empty signature
2341 (I.E. "__not_mangled_either__") */
2342 success = 0;
2344 else
2346 const char *tmp;
2348 /* Look for the LAST occurrence of __, allowing names to
2349 have the '__' sequence embedded in them. */
2350 if (!(ARM_DEMANGLING || HP_DEMANGLING))
2352 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
2353 scan = tmp;
2355 if (*(scan + 2) == '\0')
2356 success = 0;
2357 else
2358 demangle_function_name (work, mangled, declp, scan);
2362 else if (*(scan + 2) != '\0')
2364 /* Mangled name does not start with "__" but does have one somewhere
2365 in there with non empty stuff after it. Looks like a global
2366 function name. */
2367 demangle_function_name (work, mangled, declp, scan);
2369 else
2371 /* Doesn't look like a mangled name */
2372 success = 0;
2375 if (!success && (work->constructor == 2 || work->destructor == 2))
2377 string_append (declp, *mangled);
2378 *mangled += strlen (*mangled);
2379 success = 1;
2381 return (success);
2386 LOCAL FUNCTION
2388 gnu_special -- special handling of gnu mangled strings
2390 SYNOPSIS
2392 static int
2393 gnu_special (struct work_stuff *work, const char **mangled,
2394 string *declp);
2397 DESCRIPTION
2399 Process some special GNU style mangling forms that don't fit
2400 the normal pattern. For example:
2402 _$_3foo (destructor for class foo)
2403 _vt$foo (foo virtual table)
2404 _vt$foo$bar (foo::bar virtual table)
2405 __vt_foo (foo virtual table, new style with thunks)
2406 _3foo$varname (static data member)
2407 _Q22rs2tu$vw (static data member)
2408 __t6vector1Zii (constructor with template)
2409 __thunk_4__$_7ostream (virtual function thunk)
2412 static int
2413 gnu_special (work, mangled, declp)
2414 struct work_stuff *work;
2415 const char **mangled;
2416 string *declp;
2418 int n;
2419 int success = 1;
2420 const char *p;
2422 if ((*mangled)[0] == '_'
2423 && strchr (cplus_markers, (*mangled)[1]) != NULL
2424 && (*mangled)[2] == '_')
2426 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2427 (*mangled) += 3;
2428 work -> destructor += 1;
2430 else if ((*mangled)[0] == '_'
2431 && (((*mangled)[1] == '_'
2432 && (*mangled)[2] == 'v'
2433 && (*mangled)[3] == 't'
2434 && (*mangled)[4] == '_')
2435 || ((*mangled)[1] == 'v'
2436 && (*mangled)[2] == 't'
2437 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2439 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2440 and create the decl. Note that we consume the entire mangled
2441 input string, which means that demangle_signature has no work
2442 to do. */
2443 if ((*mangled)[2] == 'v')
2444 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2445 else
2446 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2447 while (**mangled != '\0')
2449 switch (**mangled)
2451 case 'Q':
2452 case 'K':
2453 success = demangle_qualified (work, mangled, declp, 0, 1);
2454 break;
2455 case 't':
2456 success = demangle_template (work, mangled, declp, 0, 1,
2458 break;
2459 default:
2460 if (isdigit((unsigned char)*mangled[0]))
2462 n = consume_count(mangled);
2463 /* We may be seeing a too-large size, or else a
2464 ".<digits>" indicating a static local symbol. In
2465 any case, declare victory and move on; *don't* try
2466 to use n to allocate. */
2467 if (n > (int) strlen (*mangled))
2469 success = 1;
2470 break;
2473 else
2475 n = strcspn (*mangled, cplus_markers);
2477 string_appendn (declp, *mangled, n);
2478 (*mangled) += n;
2481 p = strpbrk (*mangled, cplus_markers);
2482 if (success && ((p == NULL) || (p == *mangled)))
2484 if (p != NULL)
2486 string_append (declp, SCOPE_STRING (work));
2487 (*mangled)++;
2490 else
2492 success = 0;
2493 break;
2496 if (success)
2497 string_append (declp, " virtual table");
2499 else if ((*mangled)[0] == '_'
2500 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2501 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2503 /* static data member, "_3foo$varname" for example */
2504 (*mangled)++;
2505 switch (**mangled)
2507 case 'Q':
2508 case 'K':
2509 success = demangle_qualified (work, mangled, declp, 0, 1);
2510 break;
2511 case 't':
2512 success = demangle_template (work, mangled, declp, 0, 1, 1);
2513 break;
2514 default:
2515 n = consume_count (mangled);
2516 if (n < 0 || n > (long) strlen (*mangled))
2518 success = 0;
2519 break;
2521 string_appendn (declp, *mangled, n);
2522 (*mangled) += n;
2524 if (success && (p == *mangled))
2526 /* Consumed everything up to the cplus_marker, append the
2527 variable name. */
2528 (*mangled)++;
2529 string_append (declp, SCOPE_STRING (work));
2530 n = strlen (*mangled);
2531 string_appendn (declp, *mangled, n);
2532 (*mangled) += n;
2534 else
2536 success = 0;
2539 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2541 int delta;
2543 (*mangled) += 8;
2544 delta = consume_count (mangled);
2545 if (delta == -1)
2546 success = 0;
2547 else
2549 char *method = internal_cplus_demangle (work, ++*mangled);
2551 if (method)
2553 char buf[50];
2554 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2555 string_append (declp, buf);
2556 string_append (declp, method);
2557 free (method);
2558 n = strlen (*mangled);
2559 (*mangled) += n;
2561 else
2563 success = 0;
2567 else if (strncmp (*mangled, "__t", 3) == 0
2568 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2570 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2571 (*mangled) += 4;
2572 switch (**mangled)
2574 case 'Q':
2575 case 'K':
2576 success = demangle_qualified (work, mangled, declp, 0, 1);
2577 break;
2578 case 't':
2579 success = demangle_template (work, mangled, declp, 0, 1, 1);
2580 break;
2581 default:
2582 success = demangle_fund_type (work, mangled, declp);
2583 break;
2585 if (success && **mangled != '\0')
2586 success = 0;
2587 if (success)
2588 string_append (declp, p);
2590 else
2592 success = 0;
2594 return (success);
2597 static void
2598 recursively_demangle(work, mangled, result, namelength)
2599 struct work_stuff *work;
2600 const char **mangled;
2601 string *result;
2602 int namelength;
2604 char * recurse = (char *)NULL;
2605 char * recurse_dem = (char *)NULL;
2607 recurse = (char *) xmalloc (namelength + 1);
2608 memcpy (recurse, *mangled, namelength);
2609 recurse[namelength] = '\000';
2611 recurse_dem = cplus_demangle (recurse, work->options);
2613 if (recurse_dem)
2615 string_append (result, recurse_dem);
2616 free (recurse_dem);
2618 else
2620 string_appendn (result, *mangled, namelength);
2622 free (recurse);
2623 *mangled += namelength;
2628 LOCAL FUNCTION
2630 arm_special -- special handling of ARM/lucid mangled strings
2632 SYNOPSIS
2634 static int
2635 arm_special (const char **mangled,
2636 string *declp);
2639 DESCRIPTION
2641 Process some special ARM style mangling forms that don't fit
2642 the normal pattern. For example:
2644 __vtbl__3foo (foo virtual table)
2645 __vtbl__3foo__3bar (bar::foo virtual table)
2649 static int
2650 arm_special (mangled, declp)
2651 const char **mangled;
2652 string *declp;
2654 int n;
2655 int success = 1;
2656 const char *scan;
2658 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2660 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2661 and create the decl. Note that we consume the entire mangled
2662 input string, which means that demangle_signature has no work
2663 to do. */
2664 scan = *mangled + ARM_VTABLE_STRLEN;
2665 while (*scan != '\0') /* first check it can be demangled */
2667 n = consume_count (&scan);
2668 if (n == -1)
2670 return (0); /* no good */
2672 scan += n;
2673 if (scan[0] == '_' && scan[1] == '_')
2675 scan += 2;
2678 (*mangled) += ARM_VTABLE_STRLEN;
2679 while (**mangled != '\0')
2681 n = consume_count (mangled);
2682 if (n == -1
2683 || n > (long) strlen (*mangled))
2684 return 0;
2685 string_prependn (declp, *mangled, n);
2686 (*mangled) += n;
2687 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2689 string_prepend (declp, "::");
2690 (*mangled) += 2;
2693 string_append (declp, " virtual table");
2695 else
2697 success = 0;
2699 return (success);
2704 LOCAL FUNCTION
2706 demangle_qualified -- demangle 'Q' qualified name strings
2708 SYNOPSIS
2710 static int
2711 demangle_qualified (struct work_stuff *, const char *mangled,
2712 string *result, int isfuncname, int append);
2714 DESCRIPTION
2716 Demangle a qualified name, such as "Q25Outer5Inner" which is
2717 the mangled form of "Outer::Inner". The demangled output is
2718 prepended or appended to the result string according to the
2719 state of the append flag.
2721 If isfuncname is nonzero, then the qualified name we are building
2722 is going to be used as a member function name, so if it is a
2723 constructor or destructor function, append an appropriate
2724 constructor or destructor name. I.E. for the above example,
2725 the result for use as a constructor is "Outer::Inner::Inner"
2726 and the result for use as a destructor is "Outer::Inner::~Inner".
2728 BUGS
2730 Numeric conversion is ASCII dependent (FIXME).
2734 static int
2735 demangle_qualified (work, mangled, result, isfuncname, append)
2736 struct work_stuff *work;
2737 const char **mangled;
2738 string *result;
2739 int isfuncname;
2740 int append;
2742 int qualifiers = 0;
2743 int success = 1;
2744 char num[2];
2745 string temp;
2746 string last_name;
2747 int bindex = register_Btype (work);
2749 /* We only make use of ISFUNCNAME if the entity is a constructor or
2750 destructor. */
2751 isfuncname = (isfuncname
2752 && ((work->constructor & 1) || (work->destructor & 1)));
2754 string_init (&temp);
2755 string_init (&last_name);
2757 if ((*mangled)[0] == 'K')
2759 /* Squangling qualified name reuse */
2760 int idx;
2761 (*mangled)++;
2762 idx = consume_count_with_underscores (mangled);
2763 if (idx == -1 || idx >= work -> numk)
2764 success = 0;
2765 else
2766 string_append (&temp, work -> ktypevec[idx]);
2768 else
2769 switch ((*mangled)[1])
2771 case '_':
2772 /* GNU mangled name with more than 9 classes. The count is preceded
2773 by an underscore (to distinguish it from the <= 9 case) and followed
2774 by an underscore. */
2775 (*mangled)++;
2776 qualifiers = consume_count_with_underscores (mangled);
2777 if (qualifiers == -1)
2778 success = 0;
2779 break;
2781 case '1':
2782 case '2':
2783 case '3':
2784 case '4':
2785 case '5':
2786 case '6':
2787 case '7':
2788 case '8':
2789 case '9':
2790 /* The count is in a single digit. */
2791 num[0] = (*mangled)[1];
2792 num[1] = '\0';
2793 qualifiers = atoi (num);
2795 /* If there is an underscore after the digit, skip it. This is
2796 said to be for ARM-qualified names, but the ARM makes no
2797 mention of such an underscore. Perhaps cfront uses one. */
2798 if ((*mangled)[2] == '_')
2800 (*mangled)++;
2802 (*mangled) += 2;
2803 break;
2805 case '0':
2806 default:
2807 success = 0;
2810 if (!success)
2811 return success;
2813 /* Pick off the names and collect them in the temp buffer in the order
2814 in which they are found, separated by '::'. */
2816 while (qualifiers-- > 0)
2818 int remember_K = 1;
2819 string_clear (&last_name);
2821 if (*mangled[0] == '_')
2822 (*mangled)++;
2824 if (*mangled[0] == 't')
2826 /* Here we always append to TEMP since we will want to use
2827 the template name without the template parameters as a
2828 constructor or destructor name. The appropriate
2829 (parameter-less) value is returned by demangle_template
2830 in LAST_NAME. We do not remember the template type here,
2831 in order to match the G++ mangling algorithm. */
2832 success = demangle_template(work, mangled, &temp,
2833 &last_name, 1, 0);
2834 if (!success)
2835 break;
2837 else if (*mangled[0] == 'K')
2839 int idx;
2840 (*mangled)++;
2841 idx = consume_count_with_underscores (mangled);
2842 if (idx == -1 || idx >= work->numk)
2843 success = 0;
2844 else
2845 string_append (&temp, work->ktypevec[idx]);
2846 remember_K = 0;
2848 if (!success) break;
2850 else
2852 if (EDG_DEMANGLING)
2854 int namelength;
2855 /* Now recursively demangle the qualifier
2856 * This is necessary to deal with templates in
2857 * mangling styles like EDG */
2858 namelength = consume_count (mangled);
2859 if (namelength == -1)
2861 success = 0;
2862 break;
2864 recursively_demangle(work, mangled, &temp, namelength);
2866 else
2868 success = do_type (work, mangled, &last_name);
2869 if (!success)
2870 break;
2871 string_appends (&temp, &last_name);
2875 if (remember_K)
2876 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2878 if (qualifiers > 0)
2879 string_append (&temp, SCOPE_STRING (work));
2882 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2884 /* If we are using the result as a function name, we need to append
2885 the appropriate '::' separated constructor or destructor name.
2886 We do this here because this is the most convenient place, where
2887 we already have a pointer to the name and the length of the name. */
2889 if (isfuncname)
2891 string_append (&temp, SCOPE_STRING (work));
2892 if (work -> destructor & 1)
2893 string_append (&temp, "~");
2894 string_appends (&temp, &last_name);
2897 /* Now either prepend the temp buffer to the result, or append it,
2898 depending upon the state of the append flag. */
2900 if (append)
2901 string_appends (result, &temp);
2902 else
2904 if (!STRING_EMPTY (result))
2905 string_append (&temp, SCOPE_STRING (work));
2906 string_prepends (result, &temp);
2909 string_delete (&last_name);
2910 string_delete (&temp);
2911 return (success);
2916 LOCAL FUNCTION
2918 get_count -- convert an ascii count to integer, consuming tokens
2920 SYNOPSIS
2922 static int
2923 get_count (const char **type, int *count)
2925 DESCRIPTION
2927 Assume that *type points at a count in a mangled name; set
2928 *count to its value, and set *type to the next character after
2929 the count. There are some weird rules in effect here.
2931 If *type does not point at a string of digits, return zero.
2933 If *type points at a string of digits followed by an
2934 underscore, set *count to their value as an integer, advance
2935 *type to point *after the underscore, and return 1.
2937 If *type points at a string of digits not followed by an
2938 underscore, consume only the first digit. Set *count to its
2939 value as an integer, leave *type pointing after that digit,
2940 and return 1.
2942 The excuse for this odd behavior: in the ARM and HP demangling
2943 styles, a type can be followed by a repeat count of the form
2944 `Nxy', where:
2946 `x' is a single digit specifying how many additional copies
2947 of the type to append to the argument list, and
2949 `y' is one or more digits, specifying the zero-based index of
2950 the first repeated argument in the list. Yes, as you're
2951 unmangling the name you can figure this out yourself, but
2952 it's there anyway.
2954 So, for example, in `bar__3fooFPiN51', the first argument is a
2955 pointer to an integer (`Pi'), and then the next five arguments
2956 are the same (`N5'), and the first repeat is the function's
2957 second argument (`1').
2960 static int
2961 get_count (type, count)
2962 const char **type;
2963 int *count;
2965 const char *p;
2966 int n;
2968 if (!isdigit ((unsigned char)**type))
2969 return (0);
2970 else
2972 *count = **type - '0';
2973 (*type)++;
2974 if (isdigit ((unsigned char)**type))
2976 p = *type;
2977 n = *count;
2980 n *= 10;
2981 n += *p - '0';
2982 p++;
2984 while (isdigit ((unsigned char)*p));
2985 if (*p == '_')
2987 *type = p + 1;
2988 *count = n;
2992 return (1);
2995 /* RESULT will be initialised here; it will be freed on failure. The
2996 value returned is really a type_kind_t. */
2998 static int
2999 do_type (work, mangled, result)
3000 struct work_stuff *work;
3001 const char **mangled;
3002 string *result;
3004 int n;
3005 int done;
3006 int success;
3007 string decl;
3008 const char *remembered_type;
3009 int type_quals;
3010 string btype;
3011 type_kind_t tk = tk_none;
3013 string_init (&btype);
3014 string_init (&decl);
3015 string_init (result);
3017 done = 0;
3018 success = 1;
3019 while (success && !done)
3021 int member;
3022 switch (**mangled)
3025 /* A pointer type */
3026 case 'P':
3027 case 'p':
3028 (*mangled)++;
3029 if (! (work -> options & DMGL_JAVA))
3030 string_prepend (&decl, "*");
3031 if (tk == tk_none)
3032 tk = tk_pointer;
3033 break;
3035 /* A reference type */
3036 case 'R':
3037 (*mangled)++;
3038 string_prepend (&decl, "&");
3039 if (tk == tk_none)
3040 tk = tk_reference;
3041 break;
3043 /* An array */
3044 case 'A':
3046 ++(*mangled);
3047 if (!STRING_EMPTY (&decl)
3048 && (decl.b[0] == '*' || decl.b[0] == '&'))
3050 string_prepend (&decl, "(");
3051 string_append (&decl, ")");
3053 string_append (&decl, "[");
3054 if (**mangled != '_')
3055 success = demangle_template_value_parm (work, mangled, &decl,
3056 tk_integral);
3057 if (**mangled == '_')
3058 ++(*mangled);
3059 string_append (&decl, "]");
3060 break;
3063 /* A back reference to a previously seen type */
3064 case 'T':
3065 (*mangled)++;
3066 if (!get_count (mangled, &n) || n >= work -> ntypes)
3068 success = 0;
3070 else
3072 remembered_type = work -> typevec[n];
3073 mangled = &remembered_type;
3075 break;
3077 /* A function */
3078 case 'F':
3079 (*mangled)++;
3080 if (!STRING_EMPTY (&decl)
3081 && (decl.b[0] == '*' || decl.b[0] == '&'))
3083 string_prepend (&decl, "(");
3084 string_append (&decl, ")");
3086 /* After picking off the function args, we expect to either find the
3087 function return type (preceded by an '_') or the end of the
3088 string. */
3089 if (!demangle_nested_args (work, mangled, &decl)
3090 || (**mangled != '_' && **mangled != '\0'))
3092 success = 0;
3093 break;
3095 if (success && (**mangled == '_'))
3096 (*mangled)++;
3097 break;
3099 case 'M':
3100 case 'O':
3102 type_quals = TYPE_UNQUALIFIED;
3104 member = **mangled == 'M';
3105 (*mangled)++;
3107 string_append (&decl, ")");
3109 /* We don't need to prepend `::' for a qualified name;
3110 demangle_qualified will do that for us. */
3111 if (**mangled != 'Q')
3112 string_prepend (&decl, SCOPE_STRING (work));
3114 if (isdigit ((unsigned char)**mangled))
3116 n = consume_count (mangled);
3117 if (n == -1
3118 || (int) strlen (*mangled) < n)
3120 success = 0;
3121 break;
3123 string_prependn (&decl, *mangled, n);
3124 *mangled += n;
3126 else if (**mangled == 'X' || **mangled == 'Y')
3128 string temp;
3129 do_type (work, mangled, &temp);
3130 string_prepends (&decl, &temp);
3132 else if (**mangled == 't')
3134 string temp;
3135 string_init (&temp);
3136 success = demangle_template (work, mangled, &temp,
3137 NULL, 1, 1);
3138 if (success)
3140 string_prependn (&decl, temp.b, temp.p - temp.b);
3141 string_clear (&temp);
3143 else
3144 break;
3146 else if (**mangled == 'Q')
3148 success = demangle_qualified (work, mangled, &decl,
3149 /*isfuncnam=*/0,
3150 /*append=*/0);
3151 if (!success)
3152 break;
3154 else
3156 success = 0;
3157 break;
3160 string_prepend (&decl, "(");
3161 if (member)
3163 switch (**mangled)
3165 case 'C':
3166 case 'V':
3167 case 'u':
3168 type_quals |= code_for_qualifier (**mangled);
3169 (*mangled)++;
3170 break;
3172 default:
3173 break;
3176 if (*(*mangled)++ != 'F')
3178 success = 0;
3179 break;
3182 if ((member && !demangle_nested_args (work, mangled, &decl))
3183 || **mangled != '_')
3185 success = 0;
3186 break;
3188 (*mangled)++;
3189 if (! PRINT_ANSI_QUALIFIERS)
3191 break;
3193 if (type_quals != TYPE_UNQUALIFIED)
3195 APPEND_BLANK (&decl);
3196 string_append (&decl, qualifier_string (type_quals));
3198 break;
3200 case 'G':
3201 (*mangled)++;
3202 break;
3204 case 'C':
3205 case 'V':
3206 case 'u':
3207 if (PRINT_ANSI_QUALIFIERS)
3209 if (!STRING_EMPTY (&decl))
3210 string_prepend (&decl, " ");
3212 string_prepend (&decl, demangle_qualifier (**mangled));
3214 (*mangled)++;
3215 break;
3220 /* fall through */
3221 default:
3222 done = 1;
3223 break;
3227 if (success) switch (**mangled)
3229 /* A qualified name, such as "Outer::Inner". */
3230 case 'Q':
3231 case 'K':
3233 success = demangle_qualified (work, mangled, result, 0, 1);
3234 break;
3237 /* A back reference to a previously seen squangled type */
3238 case 'B':
3239 (*mangled)++;
3240 if (!get_count (mangled, &n) || n >= work -> numb)
3241 success = 0;
3242 else
3243 string_append (result, work->btypevec[n]);
3244 break;
3246 case 'X':
3247 case 'Y':
3248 /* A template parm. We substitute the corresponding argument. */
3250 int idx;
3252 (*mangled)++;
3253 idx = consume_count_with_underscores (mangled);
3255 if (idx == -1
3256 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3257 || consume_count_with_underscores (mangled) == -1)
3259 success = 0;
3260 break;
3263 if (work->tmpl_argvec)
3264 string_append (result, work->tmpl_argvec[idx]);
3265 else
3266 string_append_template_idx (result, idx);
3268 success = 1;
3270 break;
3272 default:
3273 success = demangle_fund_type (work, mangled, result);
3274 if (tk == tk_none)
3275 tk = (type_kind_t) success;
3276 break;
3279 if (success)
3281 if (!STRING_EMPTY (&decl))
3283 string_append (result, " ");
3284 string_appends (result, &decl);
3287 else
3288 string_delete (result);
3289 string_delete (&decl);
3291 if (success)
3292 /* Assume an integral type, if we're not sure. */
3293 return (int) ((tk == tk_none) ? tk_integral : tk);
3294 else
3295 return 0;
3298 /* Given a pointer to a type string that represents a fundamental type
3299 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3300 string in which the demangled output is being built in RESULT, and
3301 the WORK structure, decode the types and add them to the result.
3303 For example:
3305 "Ci" => "const int"
3306 "Sl" => "signed long"
3307 "CUs" => "const unsigned short"
3309 The value returned is really a type_kind_t. */
3311 static int
3312 demangle_fund_type (work, mangled, result)
3313 struct work_stuff *work;
3314 const char **mangled;
3315 string *result;
3317 int done = 0;
3318 int success = 1;
3319 char buf[10];
3320 int dec = 0;
3321 string btype;
3322 type_kind_t tk = tk_integral;
3324 string_init (&btype);
3326 /* First pick off any type qualifiers. There can be more than one. */
3328 while (!done)
3330 switch (**mangled)
3332 case 'C':
3333 case 'V':
3334 case 'u':
3335 if (PRINT_ANSI_QUALIFIERS)
3337 if (!STRING_EMPTY (result))
3338 string_prepend (result, " ");
3339 string_prepend (result, demangle_qualifier (**mangled));
3341 (*mangled)++;
3342 break;
3343 case 'U':
3344 (*mangled)++;
3345 APPEND_BLANK (result);
3346 string_append (result, "unsigned");
3347 break;
3348 case 'S': /* signed char only */
3349 (*mangled)++;
3350 APPEND_BLANK (result);
3351 string_append (result, "signed");
3352 break;
3353 case 'J':
3354 (*mangled)++;
3355 APPEND_BLANK (result);
3356 string_append (result, "__complex");
3357 break;
3358 default:
3359 done = 1;
3360 break;
3364 /* Now pick off the fundamental type. There can be only one. */
3366 switch (**mangled)
3368 case '\0':
3369 case '_':
3370 break;
3371 case 'v':
3372 (*mangled)++;
3373 APPEND_BLANK (result);
3374 string_append (result, "void");
3375 break;
3376 case 'x':
3377 (*mangled)++;
3378 APPEND_BLANK (result);
3379 string_append (result, "long long");
3380 break;
3381 case 'l':
3382 (*mangled)++;
3383 APPEND_BLANK (result);
3384 string_append (result, "long");
3385 break;
3386 case 'i':
3387 (*mangled)++;
3388 APPEND_BLANK (result);
3389 string_append (result, "int");
3390 break;
3391 case 's':
3392 (*mangled)++;
3393 APPEND_BLANK (result);
3394 string_append (result, "short");
3395 break;
3396 case 'b':
3397 (*mangled)++;
3398 APPEND_BLANK (result);
3399 string_append (result, "bool");
3400 tk = tk_bool;
3401 break;
3402 case 'c':
3403 (*mangled)++;
3404 APPEND_BLANK (result);
3405 string_append (result, "char");
3406 tk = tk_char;
3407 break;
3408 case 'w':
3409 (*mangled)++;
3410 APPEND_BLANK (result);
3411 string_append (result, "wchar_t");
3412 tk = tk_char;
3413 break;
3414 case 'r':
3415 (*mangled)++;
3416 APPEND_BLANK (result);
3417 string_append (result, "long double");
3418 tk = tk_real;
3419 break;
3420 case 'd':
3421 (*mangled)++;
3422 APPEND_BLANK (result);
3423 string_append (result, "double");
3424 tk = tk_real;
3425 break;
3426 case 'f':
3427 (*mangled)++;
3428 APPEND_BLANK (result);
3429 string_append (result, "float");
3430 tk = tk_real;
3431 break;
3432 case 'G':
3433 (*mangled)++;
3434 if (!isdigit ((unsigned char)**mangled))
3436 success = 0;
3437 break;
3439 case 'I':
3440 (*mangled)++;
3441 if (**mangled == '_')
3443 int i;
3444 (*mangled)++;
3445 for (i = 0;
3446 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3447 (*mangled)++, i++)
3448 buf[i] = **mangled;
3449 if (**mangled != '_')
3451 success = 0;
3452 break;
3454 buf[i] = '\0';
3455 (*mangled)++;
3457 else
3459 strncpy (buf, *mangled, 2);
3460 buf[2] = '\0';
3461 *mangled += min (strlen (*mangled), 2);
3463 sscanf (buf, "%x", &dec);
3464 sprintf (buf, "int%i_t", dec);
3465 APPEND_BLANK (result);
3466 string_append (result, buf);
3467 break;
3469 /* fall through */
3470 /* An explicit type, such as "6mytype" or "7integer" */
3471 case '0':
3472 case '1':
3473 case '2':
3474 case '3':
3475 case '4':
3476 case '5':
3477 case '6':
3478 case '7':
3479 case '8':
3480 case '9':
3482 int bindex = register_Btype (work);
3483 string btype;
3484 string_init (&btype);
3485 if (demangle_class_name (work, mangled, &btype)) {
3486 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3487 APPEND_BLANK (result);
3488 string_appends (result, &btype);
3490 else
3491 success = 0;
3492 string_delete (&btype);
3493 break;
3495 case 't':
3497 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3498 string_appends (result, &btype);
3499 break;
3501 default:
3502 success = 0;
3503 break;
3506 return success ? ((int) tk) : 0;
3510 /* Handle a template's value parameter for HP aCC (extension from ARM)
3511 **mangled points to 'S' or 'U' */
3513 static int
3514 do_hpacc_template_const_value (work, mangled, result)
3515 struct work_stuff *work ATTRIBUTE_UNUSED;
3516 const char **mangled;
3517 string *result;
3519 int unsigned_const;
3521 if (**mangled != 'U' && **mangled != 'S')
3522 return 0;
3524 unsigned_const = (**mangled == 'U');
3526 (*mangled)++;
3528 switch (**mangled)
3530 case 'N':
3531 string_append (result, "-");
3532 /* fall through */
3533 case 'P':
3534 (*mangled)++;
3535 break;
3536 case 'M':
3537 /* special case for -2^31 */
3538 string_append (result, "-2147483648");
3539 (*mangled)++;
3540 return 1;
3541 default:
3542 return 0;
3545 /* We have to be looking at an integer now */
3546 if (!(isdigit ((unsigned char)**mangled)))
3547 return 0;
3549 /* We only deal with integral values for template
3550 parameters -- so it's OK to look only for digits */
3551 while (isdigit ((unsigned char)**mangled))
3553 char_str[0] = **mangled;
3554 string_append (result, char_str);
3555 (*mangled)++;
3558 if (unsigned_const)
3559 string_append (result, "U");
3561 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3562 with L or LL suffixes. pai/1997-09-03 */
3564 return 1; /* success */
3567 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3568 **mangled is pointing to the 'A' */
3570 static int
3571 do_hpacc_template_literal (work, mangled, result)
3572 struct work_stuff *work;
3573 const char **mangled;
3574 string *result;
3576 int literal_len = 0;
3577 char * recurse;
3578 char * recurse_dem;
3580 if (**mangled != 'A')
3581 return 0;
3583 (*mangled)++;
3585 literal_len = consume_count (mangled);
3587 if (literal_len <= 0)
3588 return 0;
3590 /* Literal parameters are names of arrays, functions, etc. and the
3591 canonical representation uses the address operator */
3592 string_append (result, "&");
3594 /* Now recursively demangle the literal name */
3595 recurse = (char *) xmalloc (literal_len + 1);
3596 memcpy (recurse, *mangled, literal_len);
3597 recurse[literal_len] = '\000';
3599 recurse_dem = cplus_demangle (recurse, work->options);
3601 if (recurse_dem)
3603 string_append (result, recurse_dem);
3604 free (recurse_dem);
3606 else
3608 string_appendn (result, *mangled, literal_len);
3610 (*mangled) += literal_len;
3611 free (recurse);
3613 return 1;
3616 static int
3617 snarf_numeric_literal (args, arg)
3618 const char ** args;
3619 string * arg;
3621 if (**args == '-')
3623 char_str[0] = '-';
3624 string_append (arg, char_str);
3625 (*args)++;
3627 else if (**args == '+')
3628 (*args)++;
3630 if (!isdigit ((unsigned char)**args))
3631 return 0;
3633 while (isdigit ((unsigned char)**args))
3635 char_str[0] = **args;
3636 string_append (arg, char_str);
3637 (*args)++;
3640 return 1;
3643 /* Demangle the next argument, given by MANGLED into RESULT, which
3644 *should be an uninitialized* string. It will be initialized here,
3645 and free'd should anything go wrong. */
3647 static int
3648 do_arg (work, mangled, result)
3649 struct work_stuff *work;
3650 const char **mangled;
3651 string *result;
3653 /* Remember where we started so that we can record the type, for
3654 non-squangling type remembering. */
3655 const char *start = *mangled;
3657 string_init (result);
3659 if (work->nrepeats > 0)
3661 --work->nrepeats;
3663 if (work->previous_argument == 0)
3664 return 0;
3666 /* We want to reissue the previous type in this argument list. */
3667 string_appends (result, work->previous_argument);
3668 return 1;
3671 if (**mangled == 'n')
3673 /* A squangling-style repeat. */
3674 (*mangled)++;
3675 work->nrepeats = consume_count(mangled);
3677 if (work->nrepeats <= 0)
3678 /* This was not a repeat count after all. */
3679 return 0;
3681 if (work->nrepeats > 9)
3683 if (**mangled != '_')
3684 /* The repeat count should be followed by an '_' in this
3685 case. */
3686 return 0;
3687 else
3688 (*mangled)++;
3691 /* Now, the repeat is all set up. */
3692 return do_arg (work, mangled, result);
3695 /* Save the result in WORK->previous_argument so that we can find it
3696 if it's repeated. Note that saving START is not good enough: we
3697 do not want to add additional types to the back-referenceable
3698 type vector when processing a repeated type. */
3699 if (work->previous_argument)
3700 string_clear (work->previous_argument);
3701 else
3703 work->previous_argument = (string*) xmalloc (sizeof (string));
3704 string_init (work->previous_argument);
3707 if (!do_type (work, mangled, work->previous_argument))
3708 return 0;
3710 string_appends (result, work->previous_argument);
3712 remember_type (work, start, *mangled - start);
3713 return 1;
3716 static void
3717 remember_type (work, start, len)
3718 struct work_stuff *work;
3719 const char *start;
3720 int len;
3722 char *tem;
3724 if (work->forgetting_types)
3725 return;
3727 if (work -> ntypes >= work -> typevec_size)
3729 if (work -> typevec_size == 0)
3731 work -> typevec_size = 3;
3732 work -> typevec
3733 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3735 else
3737 work -> typevec_size *= 2;
3738 work -> typevec
3739 = (char **) xrealloc ((char *)work -> typevec,
3740 sizeof (char *) * work -> typevec_size);
3743 tem = xmalloc (len + 1);
3744 memcpy (tem, start, len);
3745 tem[len] = '\0';
3746 work -> typevec[work -> ntypes++] = tem;
3750 /* Remember a K type class qualifier. */
3751 static void
3752 remember_Ktype (work, start, len)
3753 struct work_stuff *work;
3754 const char *start;
3755 int len;
3757 char *tem;
3759 if (work -> numk >= work -> ksize)
3761 if (work -> ksize == 0)
3763 work -> ksize = 5;
3764 work -> ktypevec
3765 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3767 else
3769 work -> ksize *= 2;
3770 work -> ktypevec
3771 = (char **) xrealloc ((char *)work -> ktypevec,
3772 sizeof (char *) * work -> ksize);
3775 tem = xmalloc (len + 1);
3776 memcpy (tem, start, len);
3777 tem[len] = '\0';
3778 work -> ktypevec[work -> numk++] = tem;
3781 /* Register a B code, and get an index for it. B codes are registered
3782 as they are seen, rather than as they are completed, so map<temp<char> >
3783 registers map<temp<char> > as B0, and temp<char> as B1 */
3785 static int
3786 register_Btype (work)
3787 struct work_stuff *work;
3789 int ret;
3791 if (work -> numb >= work -> bsize)
3793 if (work -> bsize == 0)
3795 work -> bsize = 5;
3796 work -> btypevec
3797 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3799 else
3801 work -> bsize *= 2;
3802 work -> btypevec
3803 = (char **) xrealloc ((char *)work -> btypevec,
3804 sizeof (char *) * work -> bsize);
3807 ret = work -> numb++;
3808 work -> btypevec[ret] = NULL;
3809 return(ret);
3812 /* Store a value into a previously registered B code type. */
3814 static void
3815 remember_Btype (work, start, len, index)
3816 struct work_stuff *work;
3817 const char *start;
3818 int len, index;
3820 char *tem;
3822 tem = xmalloc (len + 1);
3823 memcpy (tem, start, len);
3824 tem[len] = '\0';
3825 work -> btypevec[index] = tem;
3828 /* Lose all the info related to B and K type codes. */
3829 static void
3830 forget_B_and_K_types (work)
3831 struct work_stuff *work;
3833 int i;
3835 while (work -> numk > 0)
3837 i = --(work -> numk);
3838 if (work -> ktypevec[i] != NULL)
3840 free (work -> ktypevec[i]);
3841 work -> ktypevec[i] = NULL;
3845 while (work -> numb > 0)
3847 i = --(work -> numb);
3848 if (work -> btypevec[i] != NULL)
3850 free (work -> btypevec[i]);
3851 work -> btypevec[i] = NULL;
3855 /* Forget the remembered types, but not the type vector itself. */
3857 static void
3858 forget_types (work)
3859 struct work_stuff *work;
3861 int i;
3863 while (work -> ntypes > 0)
3865 i = --(work -> ntypes);
3866 if (work -> typevec[i] != NULL)
3868 free (work -> typevec[i]);
3869 work -> typevec[i] = NULL;
3874 /* Process the argument list part of the signature, after any class spec
3875 has been consumed, as well as the first 'F' character (if any). For
3876 example:
3878 "__als__3fooRT0" => process "RT0"
3879 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3881 DECLP must be already initialised, usually non-empty. It won't be freed
3882 on failure.
3884 Note that g++ differs significantly from ARM and lucid style mangling
3885 with regards to references to previously seen types. For example, given
3886 the source fragment:
3888 class foo {
3889 public:
3890 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3893 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3894 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3896 g++ produces the names:
3898 __3fooiRT0iT2iT2
3899 foo__FiR3fooiT1iT1
3901 while lcc (and presumably other ARM style compilers as well) produces:
3903 foo__FiR3fooT1T2T1T2
3904 __ct__3fooFiR3fooT1T2T1T2
3906 Note that g++ bases its type numbers starting at zero and counts all
3907 previously seen types, while lucid/ARM bases its type numbers starting
3908 at one and only considers types after it has seen the 'F' character
3909 indicating the start of the function args. For lucid/ARM style, we
3910 account for this difference by discarding any previously seen types when
3911 we see the 'F' character, and subtracting one from the type number
3912 reference.
3916 static int
3917 demangle_args (work, mangled, declp)
3918 struct work_stuff *work;
3919 const char **mangled;
3920 string *declp;
3922 string arg;
3923 int need_comma = 0;
3924 int r;
3925 int t;
3926 const char *tem;
3927 char temptype;
3929 if (PRINT_ARG_TYPES)
3931 string_append (declp, "(");
3932 if (**mangled == '\0')
3934 string_append (declp, "void");
3938 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3939 || work->nrepeats > 0)
3941 if ((**mangled == 'N') || (**mangled == 'T'))
3943 temptype = *(*mangled)++;
3945 if (temptype == 'N')
3947 if (!get_count (mangled, &r))
3949 return (0);
3952 else
3954 r = 1;
3956 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3958 /* If we have 10 or more types we might have more than a 1 digit
3959 index so we'll have to consume the whole count here. This
3960 will lose if the next thing is a type name preceded by a
3961 count but it's impossible to demangle that case properly
3962 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3963 Pc, ...)" or "(..., type12, char *, ...)" */
3964 if ((t = consume_count(mangled)) <= 0)
3966 return (0);
3969 else
3971 if (!get_count (mangled, &t))
3973 return (0);
3976 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3978 t--;
3980 /* Validate the type index. Protect against illegal indices from
3981 malformed type strings. */
3982 if ((t < 0) || (t >= work -> ntypes))
3984 return (0);
3986 while (work->nrepeats > 0 || --r >= 0)
3988 tem = work -> typevec[t];
3989 if (need_comma && PRINT_ARG_TYPES)
3991 string_append (declp, ", ");
3993 if (!do_arg (work, &tem, &arg))
3995 return (0);
3997 if (PRINT_ARG_TYPES)
3999 string_appends (declp, &arg);
4001 string_delete (&arg);
4002 need_comma = 1;
4005 else
4007 if (need_comma && PRINT_ARG_TYPES)
4008 string_append (declp, ", ");
4009 if (!do_arg (work, mangled, &arg))
4010 return (0);
4011 if (PRINT_ARG_TYPES)
4012 string_appends (declp, &arg);
4013 string_delete (&arg);
4014 need_comma = 1;
4018 if (**mangled == 'e')
4020 (*mangled)++;
4021 if (PRINT_ARG_TYPES)
4023 if (need_comma)
4025 string_append (declp, ",");
4027 string_append (declp, "...");
4031 if (PRINT_ARG_TYPES)
4033 string_append (declp, ")");
4035 return (1);
4038 /* Like demangle_args, but for demangling the argument lists of function
4039 and method pointers or references, not top-level declarations. */
4041 static int
4042 demangle_nested_args (work, mangled, declp)
4043 struct work_stuff *work;
4044 const char **mangled;
4045 string *declp;
4047 string* saved_previous_argument;
4048 int result;
4049 int saved_nrepeats;
4051 /* The G++ name-mangling algorithm does not remember types on nested
4052 argument lists, unless -fsquangling is used, and in that case the
4053 type vector updated by remember_type is not used. So, we turn
4054 off remembering of types here. */
4055 ++work->forgetting_types;
4057 /* For the repeat codes used with -fsquangling, we must keep track of
4058 the last argument. */
4059 saved_previous_argument = work->previous_argument;
4060 saved_nrepeats = work->nrepeats;
4061 work->previous_argument = 0;
4062 work->nrepeats = 0;
4064 /* Actually demangle the arguments. */
4065 result = demangle_args (work, mangled, declp);
4067 /* Restore the previous_argument field. */
4068 if (work->previous_argument)
4069 string_delete (work->previous_argument);
4070 work->previous_argument = saved_previous_argument;
4071 --work->forgetting_types;
4072 work->nrepeats = saved_nrepeats;
4074 return result;
4077 static void
4078 demangle_function_name (work, mangled, declp, scan)
4079 struct work_stuff *work;
4080 const char **mangled;
4081 string *declp;
4082 const char *scan;
4084 size_t i;
4085 string type;
4086 const char *tem;
4088 string_appendn (declp, (*mangled), scan - (*mangled));
4089 string_need (declp, 1);
4090 *(declp -> p) = '\0';
4092 /* Consume the function name, including the "__" separating the name
4093 from the signature. We are guaranteed that SCAN points to the
4094 separator. */
4096 (*mangled) = scan + 2;
4097 /* We may be looking at an instantiation of a template function:
4098 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4099 following _F marks the start of the function arguments. Handle
4100 the template arguments first. */
4102 if (HP_DEMANGLING && (**mangled == 'X'))
4104 demangle_arm_hp_template (work, mangled, 0, declp);
4105 /* This leaves MANGLED pointing to the 'F' marking func args */
4108 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4111 /* See if we have an ARM style constructor or destructor operator.
4112 If so, then just record it, clear the decl, and return.
4113 We can't build the actual constructor/destructor decl until later,
4114 when we recover the class name from the signature. */
4116 if (strcmp (declp -> b, "__ct") == 0)
4118 work -> constructor += 1;
4119 string_clear (declp);
4120 return;
4122 else if (strcmp (declp -> b, "__dt") == 0)
4124 work -> destructor += 1;
4125 string_clear (declp);
4126 return;
4130 if (declp->p - declp->b >= 3
4131 && declp->b[0] == 'o'
4132 && declp->b[1] == 'p'
4133 && strchr (cplus_markers, declp->b[2]) != NULL)
4135 /* see if it's an assignment expression */
4136 if (declp->p - declp->b >= 10 /* op$assign_ */
4137 && memcmp (declp->b + 3, "assign_", 7) == 0)
4139 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4141 int len = declp->p - declp->b - 10;
4142 if ((int) strlen (optable[i].in) == len
4143 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4145 string_clear (declp);
4146 string_append (declp, "operator");
4147 string_append (declp, optable[i].out);
4148 string_append (declp, "=");
4149 break;
4153 else
4155 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4157 int len = declp->p - declp->b - 3;
4158 if ((int) strlen (optable[i].in) == len
4159 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4161 string_clear (declp);
4162 string_append (declp, "operator");
4163 string_append (declp, optable[i].out);
4164 break;
4169 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4170 && strchr (cplus_markers, declp->b[4]) != NULL)
4172 /* type conversion operator */
4173 tem = declp->b + 5;
4174 if (do_type (work, &tem, &type))
4176 string_clear (declp);
4177 string_append (declp, "operator ");
4178 string_appends (declp, &type);
4179 string_delete (&type);
4182 else if (declp->b[0] == '_' && declp->b[1] == '_'
4183 && declp->b[2] == 'o' && declp->b[3] == 'p')
4185 /* ANSI. */
4186 /* type conversion operator. */
4187 tem = declp->b + 4;
4188 if (do_type (work, &tem, &type))
4190 string_clear (declp);
4191 string_append (declp, "operator ");
4192 string_appends (declp, &type);
4193 string_delete (&type);
4196 else if (declp->b[0] == '_' && declp->b[1] == '_'
4197 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4198 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4200 if (declp->b[4] == '\0')
4202 /* Operator. */
4203 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4205 if (strlen (optable[i].in) == 2
4206 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4208 string_clear (declp);
4209 string_append (declp, "operator");
4210 string_append (declp, optable[i].out);
4211 break;
4215 else
4217 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4219 /* Assignment. */
4220 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4222 if (strlen (optable[i].in) == 3
4223 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4225 string_clear (declp);
4226 string_append (declp, "operator");
4227 string_append (declp, optable[i].out);
4228 break;
4236 /* a mini string-handling package */
4238 static void
4239 string_need (s, n)
4240 string *s;
4241 int n;
4243 int tem;
4245 if (s->b == NULL)
4247 if (n < 32)
4249 n = 32;
4251 s->p = s->b = xmalloc (n);
4252 s->e = s->b + n;
4254 else if (s->e - s->p < n)
4256 tem = s->p - s->b;
4257 n += tem;
4258 n *= 2;
4259 s->b = xrealloc (s->b, n);
4260 s->p = s->b + tem;
4261 s->e = s->b + n;
4265 static void
4266 string_delete (s)
4267 string *s;
4269 if (s->b != NULL)
4271 free (s->b);
4272 s->b = s->e = s->p = NULL;
4276 static void
4277 string_init (s)
4278 string *s;
4280 s->b = s->p = s->e = NULL;
4283 static void
4284 string_clear (s)
4285 string *s;
4287 s->p = s->b;
4290 #if 0
4292 static int
4293 string_empty (s)
4294 string *s;
4296 return (s->b == s->p);
4299 #endif
4301 static void
4302 string_append (p, s)
4303 string *p;
4304 const char *s;
4306 int n;
4307 if (s == NULL || *s == '\0')
4308 return;
4309 n = strlen (s);
4310 string_need (p, n);
4311 memcpy (p->p, s, n);
4312 p->p += n;
4315 static void
4316 string_appends (p, s)
4317 string *p, *s;
4319 int n;
4321 if (s->b != s->p)
4323 n = s->p - s->b;
4324 string_need (p, n);
4325 memcpy (p->p, s->b, n);
4326 p->p += n;
4330 static void
4331 string_appendn (p, s, n)
4332 string *p;
4333 const char *s;
4334 int n;
4336 if (n != 0)
4338 string_need (p, n);
4339 memcpy (p->p, s, n);
4340 p->p += n;
4344 static void
4345 string_prepend (p, s)
4346 string *p;
4347 const char *s;
4349 if (s != NULL && *s != '\0')
4351 string_prependn (p, s, strlen (s));
4355 static void
4356 string_prepends (p, s)
4357 string *p, *s;
4359 if (s->b != s->p)
4361 string_prependn (p, s->b, s->p - s->b);
4365 static void
4366 string_prependn (p, s, n)
4367 string *p;
4368 const char *s;
4369 int n;
4371 char *q;
4373 if (n != 0)
4375 string_need (p, n);
4376 for (q = p->p - 1; q >= p->b; q--)
4378 q[n] = q[0];
4380 memcpy (p->b, s, n);
4381 p->p += n;
4385 static void
4386 string_append_template_idx (s, idx)
4387 string *s;
4388 int idx;
4390 char buf[INTBUF_SIZE + 1 /* 'T' */];
4391 sprintf(buf, "T%d", idx);
4392 string_append (s, buf);
4395 /* To generate a standalone demangler program for testing purposes,
4396 just compile and link this file with -DMAIN and libiberty.a. When
4397 run, it demangles each command line arg, or each stdin string, and
4398 prints the result on stdout. */
4400 #ifdef MAIN
4402 #include "getopt.h"
4404 static const char *program_name;
4405 static const char *program_version = VERSION;
4406 static int flags = DMGL_PARAMS | DMGL_ANSI;
4408 static void demangle_it PARAMS ((char *));
4409 static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
4410 static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
4412 static void
4413 demangle_it (mangled_name)
4414 char *mangled_name;
4416 char *result;
4418 result = cplus_demangle (mangled_name, flags);
4419 if (result == NULL)
4421 printf ("%s\n", mangled_name);
4423 else
4425 printf ("%s\n", result);
4426 free (result);
4430 static void
4431 usage (stream, status)
4432 FILE *stream;
4433 int status;
4435 fprintf (stream, "\
4436 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4437 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4438 [--help] [--version] [arg...]\n",
4439 program_name);
4440 exit (status);
4443 #define MBUF_SIZE 32767
4444 char mbuffer[MBUF_SIZE];
4446 /* Defined in the automatically-generated underscore.c. */
4447 extern int prepends_underscore;
4449 int strip_underscore = 0;
4451 static struct option long_options[] = {
4452 {"strip-underscores", no_argument, 0, '_'},
4453 {"format", required_argument, 0, 's'},
4454 {"help", no_argument, 0, 'h'},
4455 {"java", no_argument, 0, 'j'},
4456 {"no-strip-underscores", no_argument, 0, 'n'},
4457 {"version", no_argument, 0, 'v'},
4458 {0, no_argument, 0, 0}
4461 /* More 'friendly' abort that prints the line and file.
4462 config.h can #define abort fancy_abort if you like that sort of thing. */
4464 void
4465 fancy_abort ()
4467 fatal ("Internal gcc abort.");
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 */