* i386.h (SPECIAL_MODE_PREDICATES): New.
[official-gcc.git] / libiberty / cplus-dem.c
blob6a6bc1afa9aaf11cce9104820dc364551d648748
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 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
58 static const char *mystrstr PARAMS ((const char *, const char *));
60 static const char *
61 mystrstr (s1, s2)
62 const char *s1, *s2;
64 register const char *p = s1;
65 register int len = strlen (s2);
67 for (; (p = strchr (p, *s2)) != 0; p++)
69 if (strncmp (p, s2, len) == 0)
71 return (p);
74 return (0);
77 /* In order to allow a single demangler executable to demangle strings
78 using various common values of CPLUS_MARKER, as well as any specific
79 one set at compile time, we maintain a string containing all the
80 commonly used ones, and check to see if the marker we are looking for
81 is in that string. CPLUS_MARKER is usually '$' on systems where the
82 assembler can deal with that. Where the assembler can't, it's usually
83 '.' (but on many systems '.' is used for other things). We put the
84 current defined CPLUS_MARKER first (which defaults to '$'), followed
85 by the next most common value, followed by an explicit '$' in case
86 the value of CPLUS_MARKER is not '$'.
88 We could avoid this if we could just get g++ to tell us what the actual
89 cplus marker character is as part of the debug information, perhaps by
90 ensuring that it is the character that terminates the gcc<n>_compiled
91 marker symbol (FIXME). */
93 #if !defined (CPLUS_MARKER)
94 #define CPLUS_MARKER '$'
95 #endif
97 enum demangling_styles current_demangling_style = gnu_demangling;
99 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
101 static char char_str[2] = { '\000', '\000' };
103 void
104 set_cplus_marker_for_demangling (ch)
105 int ch;
107 cplus_markers[0] = ch;
110 typedef struct string /* Beware: these aren't required to be */
111 { /* '\0' terminated. */
112 char *b; /* pointer to start of string */
113 char *p; /* pointer after last character */
114 char *e; /* pointer after end of allocated space */
115 } string;
117 /* Stuff that is shared between sub-routines.
118 Using a shared structure allows cplus_demangle to be reentrant. */
120 struct work_stuff
122 int options;
123 char **typevec;
124 char **ktypevec;
125 char **btypevec;
126 int numk;
127 int numb;
128 int ksize;
129 int bsize;
130 int ntypes;
131 int typevec_size;
132 int constructor;
133 int destructor;
134 int static_type; /* A static member function */
135 int temp_start; /* index in demangled to start of template args */
136 int type_quals; /* The type qualifiers. */
137 int dllimported; /* Symbol imported from a PE DLL */
138 char **tmpl_argvec; /* Template function arguments. */
139 int ntmpl_args; /* The number of template function arguments. */
140 int forgetting_types; /* Nonzero if we are not remembering the types
141 we see. */
142 string* previous_argument; /* The last function argument demangled. */
143 int nrepeats; /* The number of times to repeat the previous
144 argument. */
147 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
148 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
150 static const struct optable
152 const char *in;
153 const char *out;
154 int flags;
155 } optable[] = {
156 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
157 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
158 {"new", " new", 0}, /* old (1.91, and 1.x) */
159 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
160 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
161 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
162 {"as", "=", DMGL_ANSI}, /* ansi */
163 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
164 {"eq", "==", DMGL_ANSI}, /* old, ansi */
165 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
166 {"gt", ">", DMGL_ANSI}, /* old, ansi */
167 {"le", "<=", DMGL_ANSI}, /* old, ansi */
168 {"lt", "<", DMGL_ANSI}, /* old, ansi */
169 {"plus", "+", 0}, /* old */
170 {"pl", "+", DMGL_ANSI}, /* ansi */
171 {"apl", "+=", DMGL_ANSI}, /* ansi */
172 {"minus", "-", 0}, /* old */
173 {"mi", "-", DMGL_ANSI}, /* ansi */
174 {"ami", "-=", DMGL_ANSI}, /* ansi */
175 {"mult", "*", 0}, /* old */
176 {"ml", "*", DMGL_ANSI}, /* ansi */
177 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
178 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
179 {"convert", "+", 0}, /* old (unary +) */
180 {"negate", "-", 0}, /* old (unary -) */
181 {"trunc_mod", "%", 0}, /* old */
182 {"md", "%", DMGL_ANSI}, /* ansi */
183 {"amd", "%=", DMGL_ANSI}, /* ansi */
184 {"trunc_div", "/", 0}, /* old */
185 {"dv", "/", DMGL_ANSI}, /* ansi */
186 {"adv", "/=", DMGL_ANSI}, /* ansi */
187 {"truth_andif", "&&", 0}, /* old */
188 {"aa", "&&", DMGL_ANSI}, /* ansi */
189 {"truth_orif", "||", 0}, /* old */
190 {"oo", "||", DMGL_ANSI}, /* ansi */
191 {"truth_not", "!", 0}, /* old */
192 {"nt", "!", DMGL_ANSI}, /* ansi */
193 {"postincrement","++", 0}, /* old */
194 {"pp", "++", DMGL_ANSI}, /* ansi */
195 {"postdecrement","--", 0}, /* old */
196 {"mm", "--", DMGL_ANSI}, /* ansi */
197 {"bit_ior", "|", 0}, /* old */
198 {"or", "|", DMGL_ANSI}, /* ansi */
199 {"aor", "|=", DMGL_ANSI}, /* ansi */
200 {"bit_xor", "^", 0}, /* old */
201 {"er", "^", DMGL_ANSI}, /* ansi */
202 {"aer", "^=", DMGL_ANSI}, /* ansi */
203 {"bit_and", "&", 0}, /* old */
204 {"ad", "&", DMGL_ANSI}, /* ansi */
205 {"aad", "&=", DMGL_ANSI}, /* ansi */
206 {"bit_not", "~", 0}, /* old */
207 {"co", "~", DMGL_ANSI}, /* ansi */
208 {"call", "()", 0}, /* old */
209 {"cl", "()", DMGL_ANSI}, /* ansi */
210 {"alshift", "<<", 0}, /* old */
211 {"ls", "<<", DMGL_ANSI}, /* ansi */
212 {"als", "<<=", DMGL_ANSI}, /* ansi */
213 {"arshift", ">>", 0}, /* old */
214 {"rs", ">>", DMGL_ANSI}, /* ansi */
215 {"ars", ">>=", DMGL_ANSI}, /* ansi */
216 {"component", "->", 0}, /* old */
217 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
218 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
219 {"indirect", "*", 0}, /* old */
220 {"method_call", "->()", 0}, /* old */
221 {"addr", "&", 0}, /* old (unary &) */
222 {"array", "[]", 0}, /* old */
223 {"vc", "[]", DMGL_ANSI}, /* ansi */
224 {"compound", ", ", 0}, /* old */
225 {"cm", ", ", DMGL_ANSI}, /* ansi */
226 {"cond", "?:", 0}, /* old */
227 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
228 {"max", ">?", 0}, /* old */
229 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
230 {"min", "<?", 0}, /* old */
231 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
232 {"nop", "", 0}, /* old (for operator=) */
233 {"rm", "->*", DMGL_ANSI}, /* ansi */
234 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
237 /* These values are used to indicate the various type varieties.
238 They are all non-zero so that they can be used as `success'
239 values. */
240 typedef enum type_kind_t
242 tk_none,
243 tk_pointer,
244 tk_reference,
245 tk_integral,
246 tk_bool,
247 tk_char,
248 tk_real
249 } type_kind_t;
251 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
252 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
253 string_prepend(str, " ");}
254 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
255 string_append(str, " ");}
256 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
258 /* The scope separator appropriate for the language being demangled. */
260 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
262 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
263 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
265 /* Prototypes for local functions */
267 static char *
268 mop_up PARAMS ((struct work_stuff *, string *, int));
270 static void
271 squangle_mop_up PARAMS ((struct work_stuff *));
273 #if 0
274 static int
275 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
276 #endif
278 static char *
279 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
281 static int
282 demangle_template_template_parm PARAMS ((struct work_stuff *work,
283 const char **, string *));
285 static int
286 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
287 string *, int, int));
289 static int
290 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
291 const char **));
293 static int
294 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
296 static int
297 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
298 int, int));
300 static int
301 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
303 static int
304 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
306 static int
307 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
309 static int
310 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
312 static int
313 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
315 static int
316 arm_special PARAMS ((const char **, string *));
318 static void
319 string_need PARAMS ((string *, int));
321 static void
322 string_delete PARAMS ((string *));
324 static void
325 string_init PARAMS ((string *));
327 static void
328 string_clear PARAMS ((string *));
330 #if 0
331 static int
332 string_empty PARAMS ((string *));
333 #endif
335 static void
336 string_append PARAMS ((string *, const char *));
338 static void
339 string_appends PARAMS ((string *, string *));
341 static void
342 string_appendn PARAMS ((string *, const char *, int));
344 static void
345 string_prepend PARAMS ((string *, const char *));
347 static void
348 string_prependn PARAMS ((string *, const char *, int));
350 static int
351 get_count PARAMS ((const char **, int *));
353 static int
354 consume_count PARAMS ((const char **));
356 static int
357 consume_count_with_underscores PARAMS ((const char**));
359 static int
360 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
362 static int
363 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
365 static int
366 do_type PARAMS ((struct work_stuff *, const char **, string *));
368 static int
369 do_arg PARAMS ((struct work_stuff *, const char **, string *));
371 static void
372 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
373 const char *));
375 static void
376 remember_type PARAMS ((struct work_stuff *, const char *, int));
378 static void
379 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
381 static int
382 register_Btype PARAMS ((struct work_stuff *));
384 static void
385 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
387 static void
388 forget_types PARAMS ((struct work_stuff *));
390 static void
391 forget_B_and_K_types PARAMS ((struct work_stuff *));
393 static void
394 string_prepends PARAMS ((string *, string *));
396 static int
397 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
398 string*, type_kind_t));
400 static int
401 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
403 static int
404 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
406 static int
407 snarf_numeric_literal PARAMS ((const char **, string *));
409 /* There is a TYPE_QUAL value for each type qualifier. They can be
410 combined by bitwise-or to form the complete set of qualifiers for a
411 type. */
413 #define TYPE_UNQUALIFIED 0x0
414 #define TYPE_QUAL_CONST 0x1
415 #define TYPE_QUAL_VOLATILE 0x2
416 #define TYPE_QUAL_RESTRICT 0x4
418 static int
419 code_for_qualifier PARAMS ((int));
421 static const char*
422 qualifier_string PARAMS ((int));
424 static const char*
425 demangle_qualifier PARAMS ((int));
427 static int
428 demangle_integral_value PARAMS ((struct work_stuff *, const char **,
429 string *));
431 static void
432 demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
433 string *));
435 static void
436 recursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
437 int));
439 static const char *
440 standard_symbol_characters PARAMS ((void));
442 static const char *
443 hp_symbol_characters PARAMS ((void));
445 /* Translate count to integer, consuming tokens in the process.
446 Conversion terminates on the first non-digit character.
448 Trying to consume something that isn't a count results in no
449 consumption of input and a return of -1.
451 Overflow consumes the rest of the digits, and returns -1. */
453 static int
454 consume_count (type)
455 const char **type;
457 int count = 0;
459 if (! isdigit ((unsigned char)**type))
460 return -1;
462 while (isdigit ((unsigned char)**type))
464 count *= 10;
466 /* Check for overflow.
467 We assume that count is represented using two's-complement;
468 no power of two is divisible by ten, so if an overflow occurs
469 when multiplying by ten, the result will not be a multiple of
470 ten. */
471 if ((count % 10) != 0)
473 while (isdigit ((unsigned char) **type))
474 (*type)++;
475 return -1;
478 count += **type - '0';
479 (*type)++;
482 return (count);
486 /* Like consume_count, but for counts that are preceded and followed
487 by '_' if they are greater than 10. Also, -1 is returned for
488 failure, since 0 can be a valid value. */
490 static int
491 consume_count_with_underscores (mangled)
492 const char **mangled;
494 int idx;
496 if (**mangled == '_')
498 (*mangled)++;
499 if (!isdigit ((unsigned char)**mangled))
500 return -1;
502 idx = consume_count (mangled);
503 if (**mangled != '_')
504 /* The trailing underscore was missing. */
505 return -1;
507 (*mangled)++;
509 else
511 if (**mangled < '0' || **mangled > '9')
512 return -1;
514 idx = **mangled - '0';
515 (*mangled)++;
518 return idx;
521 /* C is the code for a type-qualifier. Return the TYPE_QUAL
522 corresponding to this qualifier. */
524 static int
525 code_for_qualifier (c)
526 int c;
528 switch (c)
530 case 'C':
531 return TYPE_QUAL_CONST;
533 case 'V':
534 return TYPE_QUAL_VOLATILE;
536 case 'u':
537 return TYPE_QUAL_RESTRICT;
539 default:
540 break;
543 /* C was an invalid qualifier. */
544 abort ();
547 /* Return the string corresponding to the qualifiers given by
548 TYPE_QUALS. */
550 static const char*
551 qualifier_string (type_quals)
552 int type_quals;
554 switch (type_quals)
556 case TYPE_UNQUALIFIED:
557 return "";
559 case TYPE_QUAL_CONST:
560 return "const";
562 case TYPE_QUAL_VOLATILE:
563 return "volatile";
565 case TYPE_QUAL_RESTRICT:
566 return "__restrict";
568 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
569 return "const volatile";
571 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
572 return "const __restrict";
574 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
575 return "volatile __restrict";
577 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
578 return "const volatile __restrict";
580 default:
581 break;
584 /* TYPE_QUALS was an invalid qualifier set. */
585 abort ();
588 /* C is the code for a type-qualifier. Return the string
589 corresponding to this qualifier. This function should only be
590 called with a valid qualifier code. */
592 static const char*
593 demangle_qualifier (c)
594 int c;
596 return qualifier_string (code_for_qualifier (c));
600 cplus_demangle_opname (opname, result, options)
601 const char *opname;
602 char *result;
603 int options;
605 int len, len1, ret;
606 string type;
607 struct work_stuff work[1];
608 const char *tem;
610 len = strlen(opname);
611 result[0] = '\0';
612 ret = 0;
613 memset ((char *) work, 0, sizeof (work));
614 work->options = options;
616 if (opname[0] == '_' && opname[1] == '_'
617 && opname[2] == 'o' && opname[3] == 'p')
619 /* ANSI. */
620 /* type conversion operator. */
621 tem = opname + 4;
622 if (do_type (work, &tem, &type))
624 strcat (result, "operator ");
625 strncat (result, type.b, type.p - type.b);
626 string_delete (&type);
627 ret = 1;
630 else if (opname[0] == '_' && opname[1] == '_'
631 && opname[2] >= 'a' && opname[2] <= 'z'
632 && opname[3] >= 'a' && opname[3] <= 'z')
634 if (opname[4] == '\0')
636 /* Operator. */
637 size_t i;
638 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
640 if (strlen (optable[i].in) == 2
641 && memcmp (optable[i].in, opname + 2, 2) == 0)
643 strcat (result, "operator");
644 strcat (result, optable[i].out);
645 ret = 1;
646 break;
650 else
652 if (opname[2] == 'a' && opname[5] == '\0')
654 /* Assignment. */
655 size_t i;
656 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
658 if (strlen (optable[i].in) == 3
659 && memcmp (optable[i].in, opname + 2, 3) == 0)
661 strcat (result, "operator");
662 strcat (result, optable[i].out);
663 ret = 1;
664 break;
670 else if (len >= 3
671 && opname[0] == 'o'
672 && opname[1] == 'p'
673 && strchr (cplus_markers, opname[2]) != NULL)
675 /* see if it's an assignment expression */
676 if (len >= 10 /* op$assign_ */
677 && memcmp (opname + 3, "assign_", 7) == 0)
679 size_t i;
680 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
682 len1 = len - 10;
683 if ((int) strlen (optable[i].in) == len1
684 && memcmp (optable[i].in, opname + 10, len1) == 0)
686 strcat (result, "operator");
687 strcat (result, optable[i].out);
688 strcat (result, "=");
689 ret = 1;
690 break;
694 else
696 size_t i;
697 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
699 len1 = len - 3;
700 if ((int) strlen (optable[i].in) == len1
701 && memcmp (optable[i].in, opname + 3, len1) == 0)
703 strcat (result, "operator");
704 strcat (result, optable[i].out);
705 ret = 1;
706 break;
711 else if (len >= 5 && memcmp (opname, "type", 4) == 0
712 && strchr (cplus_markers, opname[4]) != NULL)
714 /* type conversion operator */
715 tem = opname + 5;
716 if (do_type (work, &tem, &type))
718 strcat (result, "operator ");
719 strncat (result, type.b, type.p - type.b);
720 string_delete (&type);
721 ret = 1;
724 squangle_mop_up (work);
725 return ret;
728 /* Takes operator name as e.g. "++" and returns mangled
729 operator name (e.g. "postincrement_expr"), or NULL if not found.
731 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
732 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
734 const char *
735 cplus_mangle_opname (opname, options)
736 const char *opname;
737 int options;
739 size_t i;
740 int len;
742 len = strlen (opname);
743 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
745 if ((int) strlen (optable[i].out) == len
746 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
747 && memcmp (optable[i].out, opname, len) == 0)
748 return optable[i].in;
750 return (0);
753 /* char *cplus_demangle (const char *mangled, int options)
755 If MANGLED is a mangled function name produced by GNU C++, then
756 a pointer to a malloced string giving a C++ representation
757 of the name will be returned; otherwise NULL will be returned.
758 It is the caller's responsibility to free the string which
759 is returned.
761 The OPTIONS arg may contain one or more of the following bits:
763 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
764 included.
765 DMGL_PARAMS Function parameters are included.
767 For example,
769 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
770 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
771 cplus_demangle ("foo__1Ai", 0) => "A::foo"
773 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
774 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
775 cplus_demangle ("foo__1Afe", 0) => "A::foo"
777 Note that any leading underscores, or other such characters prepended by
778 the compilation system, are presumed to have already been stripped from
779 MANGLED. */
781 char *
782 cplus_demangle (mangled, options)
783 const char *mangled;
784 int options;
786 char *ret;
787 struct work_stuff work[1];
788 memset ((char *) work, 0, sizeof (work));
789 work -> options = options;
790 if ((work -> options & DMGL_STYLE_MASK) == 0)
791 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
793 ret = internal_cplus_demangle (work, mangled);
794 squangle_mop_up (work);
795 return (ret);
799 /* This function performs most of what cplus_demangle use to do, but
800 to be able to demangle a name with a B, K or n code, we need to
801 have a longer term memory of what types have been seen. The original
802 now intializes and cleans up the squangle code info, while internal
803 calls go directly to this routine to avoid resetting that info. */
805 static char *
806 internal_cplus_demangle (work, mangled)
807 struct work_stuff *work;
808 const char *mangled;
811 string decl;
812 int success = 0;
813 char *demangled = NULL;
814 int s1,s2,s3,s4;
815 s1 = work->constructor;
816 s2 = work->destructor;
817 s3 = work->static_type;
818 s4 = work->type_quals;
819 work->constructor = work->destructor = 0;
820 work->type_quals = TYPE_UNQUALIFIED;
821 work->dllimported = 0;
823 if ((mangled != NULL) && (*mangled != '\0'))
825 string_init (&decl);
827 /* First check to see if gnu style demangling is active and if the
828 string to be demangled contains a CPLUS_MARKER. If so, attempt to
829 recognize one of the gnu special forms rather than looking for a
830 standard prefix. In particular, don't worry about whether there
831 is a "__" string in the mangled string. Consider "_$_5__foo" for
832 example. */
834 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
836 success = gnu_special (work, &mangled, &decl);
838 if (!success)
840 success = demangle_prefix (work, &mangled, &decl);
842 if (success && (*mangled != '\0'))
844 success = demangle_signature (work, &mangled, &decl);
846 if (work->constructor == 2)
848 string_prepend (&decl, "global constructors keyed to ");
849 work->constructor = 0;
851 else if (work->destructor == 2)
853 string_prepend (&decl, "global destructors keyed to ");
854 work->destructor = 0;
856 else if (work->dllimported == 1)
858 string_prepend (&decl, "import stub for ");
859 work->dllimported = 0;
861 demangled = mop_up (work, &decl, success);
863 work->constructor = s1;
864 work->destructor = s2;
865 work->static_type = s3;
866 work->type_quals = s4;
867 return (demangled);
871 /* Clear out and squangling related storage */
872 static void
873 squangle_mop_up (work)
874 struct work_stuff *work;
876 /* clean up the B and K type mangling types. */
877 forget_B_and_K_types (work);
878 if (work -> btypevec != NULL)
880 free ((char *) work -> btypevec);
882 if (work -> ktypevec != NULL)
884 free ((char *) work -> ktypevec);
888 /* Clear out any mangled storage */
890 static char *
891 mop_up (work, declp, success)
892 struct work_stuff *work;
893 string *declp;
894 int success;
896 char *demangled = NULL;
898 /* Discard the remembered types, if any. */
900 forget_types (work);
901 if (work -> typevec != NULL)
903 free ((char *) work -> typevec);
904 work -> typevec = NULL;
905 work -> typevec_size = 0;
907 if (work->tmpl_argvec)
909 int i;
911 for (i = 0; i < work->ntmpl_args; i++)
912 if (work->tmpl_argvec[i])
913 free ((char*) work->tmpl_argvec[i]);
915 free ((char*) work->tmpl_argvec);
916 work->tmpl_argvec = NULL;
918 if (work->previous_argument)
920 string_delete (work->previous_argument);
921 free ((char*) work->previous_argument);
922 work->previous_argument = NULL;
925 /* If demangling was successful, ensure that the demangled string is null
926 terminated and return it. Otherwise, free the demangling decl. */
928 if (!success)
930 string_delete (declp);
932 else
934 string_appendn (declp, "", 1);
935 demangled = declp -> b;
937 return (demangled);
942 LOCAL FUNCTION
944 demangle_signature -- demangle the signature part of a mangled name
946 SYNOPSIS
948 static int
949 demangle_signature (struct work_stuff *work, const char **mangled,
950 string *declp);
952 DESCRIPTION
954 Consume and demangle the signature portion of the mangled name.
956 DECLP is the string where demangled output is being built. At
957 entry it contains the demangled root name from the mangled name
958 prefix. I.E. either a demangled operator name or the root function
959 name. In some special cases, it may contain nothing.
961 *MANGLED points to the current unconsumed location in the mangled
962 name. As tokens are consumed and demangling is performed, the
963 pointer is updated to continuously point at the next token to
964 be consumed.
966 Demangling GNU style mangled names is nasty because there is no
967 explicit token that marks the start of the outermost function
968 argument list. */
970 static int
971 demangle_signature (work, mangled, declp)
972 struct work_stuff *work;
973 const char **mangled;
974 string *declp;
976 int success = 1;
977 int func_done = 0;
978 int expect_func = 0;
979 int expect_return_type = 0;
980 const char *oldmangled = NULL;
981 string trawname;
982 string tname;
984 while (success && (**mangled != '\0'))
986 switch (**mangled)
988 case 'Q':
989 oldmangled = *mangled;
990 success = demangle_qualified (work, mangled, declp, 1, 0);
991 if (success)
992 remember_type (work, oldmangled, *mangled - oldmangled);
993 if (AUTO_DEMANGLING || GNU_DEMANGLING)
994 expect_func = 1;
995 oldmangled = NULL;
996 break;
998 case 'K':
999 oldmangled = *mangled;
1000 success = demangle_qualified (work, mangled, declp, 1, 0);
1001 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1003 expect_func = 1;
1005 oldmangled = NULL;
1006 break;
1008 case 'S':
1009 /* Static member function */
1010 if (oldmangled == NULL)
1012 oldmangled = *mangled;
1014 (*mangled)++;
1015 work -> static_type = 1;
1016 break;
1018 case 'C':
1019 case 'V':
1020 case 'u':
1021 work->type_quals |= code_for_qualifier (**mangled);
1023 /* a qualified member function */
1024 if (oldmangled == NULL)
1025 oldmangled = *mangled;
1026 (*mangled)++;
1027 break;
1029 case 'L':
1030 /* Local class name follows after "Lnnn_" */
1031 if (HP_DEMANGLING)
1033 while (**mangled && (**mangled != '_'))
1034 (*mangled)++;
1035 if (!**mangled)
1036 success = 0;
1037 else
1038 (*mangled)++;
1040 else
1041 success = 0;
1042 break;
1044 case '0': case '1': case '2': case '3': case '4':
1045 case '5': case '6': case '7': case '8': case '9':
1046 if (oldmangled == NULL)
1048 oldmangled = *mangled;
1050 work->temp_start = -1; /* uppermost call to demangle_class */
1051 success = demangle_class (work, mangled, declp);
1052 if (success)
1054 remember_type (work, oldmangled, *mangled - oldmangled);
1056 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1058 /* EDG and others will have the "F", so we let the loop cycle
1059 if we are looking at one. */
1060 if (**mangled != 'F')
1061 expect_func = 1;
1063 oldmangled = NULL;
1064 break;
1066 case 'B':
1068 string s;
1069 success = do_type (work, mangled, &s);
1070 if (success)
1072 string_append (&s, SCOPE_STRING (work));
1073 string_prepends (declp, &s);
1075 oldmangled = NULL;
1076 expect_func = 1;
1078 break;
1080 case 'F':
1081 /* Function */
1082 /* ARM/HP style demangling includes a specific 'F' character after
1083 the class name. For GNU style, it is just implied. So we can
1084 safely just consume any 'F' at this point and be compatible
1085 with either style. */
1087 oldmangled = NULL;
1088 func_done = 1;
1089 (*mangled)++;
1091 /* For lucid/ARM/HP style we have to forget any types we might
1092 have remembered up to this point, since they were not argument
1093 types. GNU style considers all types seen as available for
1094 back references. See comment in demangle_args() */
1096 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1098 forget_types (work);
1100 success = demangle_args (work, mangled, declp);
1101 /* After picking off the function args, we expect to either
1102 find the function return type (preceded by an '_') or the
1103 end of the string. */
1104 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1106 ++(*mangled);
1107 /* At this level, we do not care about the return type. */
1108 success = do_type (work, mangled, &tname);
1109 string_delete (&tname);
1112 break;
1114 case 't':
1115 /* G++ Template */
1116 string_init(&trawname);
1117 string_init(&tname);
1118 if (oldmangled == NULL)
1120 oldmangled = *mangled;
1122 success = demangle_template (work, mangled, &tname,
1123 &trawname, 1, 1);
1124 if (success)
1126 remember_type (work, oldmangled, *mangled - oldmangled);
1128 string_append (&tname, SCOPE_STRING (work));
1130 string_prepends(declp, &tname);
1131 if (work -> destructor & 1)
1133 string_prepend (&trawname, "~");
1134 string_appends (declp, &trawname);
1135 work->destructor -= 1;
1137 if ((work->constructor & 1) || (work->destructor & 1))
1139 string_appends (declp, &trawname);
1140 work->constructor -= 1;
1142 string_delete(&trawname);
1143 string_delete(&tname);
1144 oldmangled = NULL;
1145 expect_func = 1;
1146 break;
1148 case '_':
1149 if (GNU_DEMANGLING && expect_return_type)
1151 /* Read the return type. */
1152 string return_type;
1153 string_init (&return_type);
1155 (*mangled)++;
1156 success = do_type (work, mangled, &return_type);
1157 APPEND_BLANK (&return_type);
1159 string_prepends (declp, &return_type);
1160 string_delete (&return_type);
1161 break;
1163 else
1164 /* At the outermost level, we cannot have a return type specified,
1165 so if we run into another '_' at this point we are dealing with
1166 a mangled name that is either bogus, or has been mangled by
1167 some algorithm we don't know how to deal with. So just
1168 reject the entire demangling. */
1169 /* However, "_nnn" is an expected suffix for alternate entry point
1170 numbered nnn for a function, with HP aCC, so skip over that
1171 without reporting failure. pai/1997-09-04 */
1172 if (HP_DEMANGLING)
1174 (*mangled)++;
1175 while (**mangled && isdigit ((unsigned char)**mangled))
1176 (*mangled)++;
1178 else
1179 success = 0;
1180 break;
1182 case 'H':
1183 if (GNU_DEMANGLING)
1185 /* A G++ template function. Read the template arguments. */
1186 success = demangle_template (work, mangled, declp, 0, 0,
1188 if (!(work->constructor & 1))
1189 expect_return_type = 1;
1190 (*mangled)++;
1191 break;
1193 else
1194 /* fall through */
1197 default:
1198 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1200 /* Assume we have stumbled onto the first outermost function
1201 argument token, and start processing args. */
1202 func_done = 1;
1203 success = demangle_args (work, mangled, declp);
1205 else
1207 /* Non-GNU demanglers use a specific token to mark the start
1208 of the outermost function argument tokens. Typically 'F',
1209 for ARM/HP-demangling, for example. So if we find something
1210 we are not prepared for, it must be an error. */
1211 success = 0;
1213 break;
1216 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1219 if (success && expect_func)
1221 func_done = 1;
1222 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1224 forget_types (work);
1226 success = demangle_args (work, mangled, declp);
1227 /* Since template include the mangling of their return types,
1228 we must set expect_func to 0 so that we don't try do
1229 demangle more arguments the next time we get here. */
1230 expect_func = 0;
1234 if (success && !func_done)
1236 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1238 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1239 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1240 first case, and need to ensure that the '(void)' gets added to
1241 the current declp. Note that with ARM/HP, the first case
1242 represents the name of a static data member 'foo::bar',
1243 which is in the current declp, so we leave it alone. */
1244 success = demangle_args (work, mangled, declp);
1247 if (success && PRINT_ARG_TYPES)
1249 if (work->static_type)
1250 string_append (declp, " static");
1251 if (work->type_quals != TYPE_UNQUALIFIED)
1253 APPEND_BLANK (declp);
1254 string_append (declp, qualifier_string (work->type_quals));
1258 return (success);
1261 #if 0
1263 static int
1264 demangle_method_args (work, mangled, declp)
1265 struct work_stuff *work;
1266 const char **mangled;
1267 string *declp;
1269 int success = 0;
1271 if (work -> static_type)
1273 string_append (declp, *mangled + 1);
1274 *mangled += strlen (*mangled);
1275 success = 1;
1277 else
1279 success = demangle_args (work, mangled, declp);
1281 return (success);
1284 #endif
1286 static int
1287 demangle_template_template_parm (work, mangled, tname)
1288 struct work_stuff *work;
1289 const char **mangled;
1290 string *tname;
1292 int i;
1293 int r;
1294 int need_comma = 0;
1295 int success = 1;
1296 string temp;
1298 string_append (tname, "template <");
1299 /* get size of template parameter list */
1300 if (get_count (mangled, &r))
1302 for (i = 0; i < r; i++)
1304 if (need_comma)
1306 string_append (tname, ", ");
1309 /* Z for type parameters */
1310 if (**mangled == 'Z')
1312 (*mangled)++;
1313 string_append (tname, "class");
1315 /* z for template parameters */
1316 else if (**mangled == 'z')
1318 (*mangled)++;
1319 success =
1320 demangle_template_template_parm (work, mangled, tname);
1321 if (!success)
1323 break;
1326 else
1328 /* temp is initialized in do_type */
1329 success = do_type (work, mangled, &temp);
1330 if (success)
1332 string_appends (tname, &temp);
1334 string_delete(&temp);
1335 if (!success)
1337 break;
1340 need_comma = 1;
1344 if (tname->p[-1] == '>')
1345 string_append (tname, " ");
1346 string_append (tname, "> class");
1347 return (success);
1350 static int
1351 demangle_integral_value (work, mangled, s)
1352 struct work_stuff *work;
1353 const char** mangled;
1354 string* s;
1356 int success;
1358 if (**mangled == 'E')
1360 int need_operator = 0;
1362 success = 1;
1363 string_appendn (s, "(", 1);
1364 (*mangled)++;
1365 while (success && **mangled != 'W' && **mangled != '\0')
1367 if (need_operator)
1369 size_t i;
1370 size_t len;
1372 success = 0;
1374 len = strlen (*mangled);
1376 for (i = 0;
1377 i < sizeof (optable) / sizeof (optable [0]);
1378 ++i)
1380 size_t l = strlen (optable[i].in);
1382 if (l <= len
1383 && memcmp (optable[i].in, *mangled, l) == 0)
1385 string_appendn (s, " ", 1);
1386 string_append (s, optable[i].out);
1387 string_appendn (s, " ", 1);
1388 success = 1;
1389 (*mangled) += l;
1390 break;
1394 if (!success)
1395 break;
1397 else
1398 need_operator = 1;
1400 success = demangle_template_value_parm (work, mangled, s,
1401 tk_integral);
1404 if (**mangled != 'W')
1405 success = 0;
1406 else
1408 string_appendn (s, ")", 1);
1409 (*mangled)++;
1412 else if (**mangled == 'Q' || **mangled == 'K')
1413 success = demangle_qualified (work, mangled, s, 0, 1);
1414 else
1416 success = 0;
1418 if (**mangled == 'm')
1420 string_appendn (s, "-", 1);
1421 (*mangled)++;
1423 while (isdigit ((unsigned char)**mangled))
1425 string_appendn (s, *mangled, 1);
1426 (*mangled)++;
1427 success = 1;
1431 return success;
1434 static int
1435 demangle_template_value_parm (work, mangled, s, tk)
1436 struct work_stuff *work;
1437 const char **mangled;
1438 string* s;
1439 type_kind_t tk;
1441 int success = 1;
1443 if (**mangled == 'Y')
1445 /* The next argument is a template parameter. */
1446 int idx;
1448 (*mangled)++;
1449 idx = consume_count_with_underscores (mangled);
1450 if (idx == -1
1451 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1452 || consume_count_with_underscores (mangled) == -1)
1453 return -1;
1454 if (work->tmpl_argvec)
1455 string_append (s, work->tmpl_argvec[idx]);
1456 else
1458 char buf[10];
1459 sprintf(buf, "T%d", idx);
1460 string_append (s, buf);
1463 else if (tk == tk_integral)
1464 success = demangle_integral_value (work, mangled, s);
1465 else if (tk == tk_char)
1467 char tmp[2];
1468 int val;
1469 if (**mangled == 'm')
1471 string_appendn (s, "-", 1);
1472 (*mangled)++;
1474 string_appendn (s, "'", 1);
1475 val = consume_count(mangled);
1476 if (val <= 0)
1477 success = 0;
1478 else
1480 tmp[0] = (char)val;
1481 tmp[1] = '\0';
1482 string_appendn (s, &tmp[0], 1);
1483 string_appendn (s, "'", 1);
1486 else if (tk == tk_bool)
1488 int val = consume_count (mangled);
1489 if (val == 0)
1490 string_appendn (s, "false", 5);
1491 else if (val == 1)
1492 string_appendn (s, "true", 4);
1493 else
1494 success = 0;
1496 else if (tk == tk_real)
1498 if (**mangled == 'm')
1500 string_appendn (s, "-", 1);
1501 (*mangled)++;
1503 while (isdigit ((unsigned char)**mangled))
1505 string_appendn (s, *mangled, 1);
1506 (*mangled)++;
1508 if (**mangled == '.') /* fraction */
1510 string_appendn (s, ".", 1);
1511 (*mangled)++;
1512 while (isdigit ((unsigned char)**mangled))
1514 string_appendn (s, *mangled, 1);
1515 (*mangled)++;
1518 if (**mangled == 'e') /* exponent */
1520 string_appendn (s, "e", 1);
1521 (*mangled)++;
1522 while (isdigit ((unsigned char)**mangled))
1524 string_appendn (s, *mangled, 1);
1525 (*mangled)++;
1529 else if (tk == tk_pointer || tk == tk_reference)
1531 if (**mangled == 'Q')
1532 success = demangle_qualified (work, mangled, s,
1533 /*isfuncname=*/0,
1534 /*append=*/1);
1535 else
1537 int symbol_len = consume_count (mangled);
1538 if (symbol_len == -1)
1539 return -1;
1540 if (symbol_len == 0)
1541 string_appendn (s, "0", 1);
1542 else
1544 char *p = xmalloc (symbol_len + 1), *q;
1545 strncpy (p, *mangled, symbol_len);
1546 p [symbol_len] = '\0';
1547 /* We use cplus_demangle here, rather than
1548 internal_cplus_demangle, because the name of the entity
1549 mangled here does not make use of any of the squangling
1550 or type-code information we have built up thus far; it is
1551 mangled independently. */
1552 q = cplus_demangle (p, work->options);
1553 if (tk == tk_pointer)
1554 string_appendn (s, "&", 1);
1555 /* FIXME: Pointer-to-member constants should get a
1556 qualifying class name here. */
1557 if (q)
1559 string_append (s, q);
1560 free (q);
1562 else
1563 string_append (s, p);
1564 free (p);
1566 *mangled += symbol_len;
1570 return success;
1573 /* Demangle the template name in MANGLED. The full name of the
1574 template (e.g., S<int>) is placed in TNAME. The name without the
1575 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1576 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1577 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1578 the tmeplate is remembered in the list of back-referenceable
1579 types. */
1581 static int
1582 demangle_template (work, mangled, tname, trawname, is_type, remember)
1583 struct work_stuff *work;
1584 const char **mangled;
1585 string *tname;
1586 string *trawname;
1587 int is_type;
1588 int remember;
1590 int i;
1591 int r;
1592 int need_comma = 0;
1593 int success = 0;
1594 const char *start;
1595 int is_java_array = 0;
1596 string temp;
1597 int bindex = 0;
1599 (*mangled)++;
1600 if (is_type)
1602 if (remember)
1603 bindex = register_Btype (work);
1604 start = *mangled;
1605 /* get template name */
1606 if (**mangled == 'z')
1608 int idx;
1609 (*mangled)++;
1610 (*mangled)++;
1612 idx = consume_count_with_underscores (mangled);
1613 if (idx == -1
1614 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1615 || consume_count_with_underscores (mangled) == -1)
1616 return (0);
1618 if (work->tmpl_argvec)
1620 string_append (tname, work->tmpl_argvec[idx]);
1621 if (trawname)
1622 string_append (trawname, work->tmpl_argvec[idx]);
1624 else
1626 char buf[10];
1627 sprintf(buf, "T%d", idx);
1628 string_append (tname, buf);
1629 if (trawname)
1630 string_append (trawname, buf);
1633 else
1635 if ((r = consume_count (mangled)) <= 0
1636 || (int) strlen (*mangled) < r)
1638 return (0);
1640 is_java_array = (work -> options & DMGL_JAVA)
1641 && strncmp (*mangled, "JArray1Z", 8) == 0;
1642 if (! is_java_array)
1644 string_appendn (tname, *mangled, r);
1646 if (trawname)
1647 string_appendn (trawname, *mangled, r);
1648 *mangled += r;
1651 if (!is_java_array)
1652 string_append (tname, "<");
1653 /* get size of template parameter list */
1654 if (!get_count (mangled, &r))
1656 return (0);
1658 if (!is_type)
1660 /* Create an array for saving the template argument values. */
1661 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1662 work->ntmpl_args = r;
1663 for (i = 0; i < r; i++)
1664 work->tmpl_argvec[i] = 0;
1666 for (i = 0; i < r; i++)
1668 if (need_comma)
1670 string_append (tname, ", ");
1672 /* Z for type parameters */
1673 if (**mangled == 'Z')
1675 (*mangled)++;
1676 /* temp is initialized in do_type */
1677 success = do_type (work, mangled, &temp);
1678 if (success)
1680 string_appends (tname, &temp);
1682 if (!is_type)
1684 /* Save the template argument. */
1685 int len = temp.p - temp.b;
1686 work->tmpl_argvec[i] = xmalloc (len + 1);
1687 memcpy (work->tmpl_argvec[i], temp.b, len);
1688 work->tmpl_argvec[i][len] = '\0';
1691 string_delete(&temp);
1692 if (!success)
1694 break;
1697 /* z for template parameters */
1698 else if (**mangled == 'z')
1700 int r2;
1701 (*mangled)++;
1702 success = demangle_template_template_parm (work, mangled, tname);
1704 if (success
1705 && (r2 = consume_count (mangled)) > 0
1706 && (int) strlen (*mangled) >= r2)
1708 string_append (tname, " ");
1709 string_appendn (tname, *mangled, r2);
1710 if (!is_type)
1712 /* Save the template argument. */
1713 int len = r2;
1714 work->tmpl_argvec[i] = xmalloc (len + 1);
1715 memcpy (work->tmpl_argvec[i], *mangled, len);
1716 work->tmpl_argvec[i][len] = '\0';
1718 *mangled += r2;
1720 if (!success)
1722 break;
1725 else
1727 string param;
1728 string* s;
1730 /* otherwise, value parameter */
1732 /* temp is initialized in do_type */
1733 success = do_type (work, mangled, &temp);
1734 string_delete(&temp);
1735 if (!success)
1736 break;
1738 if (!is_type)
1740 s = &param;
1741 string_init (s);
1743 else
1744 s = tname;
1746 success = demangle_template_value_parm (work, mangled, s,
1747 (type_kind_t) success);
1749 if (!success)
1751 if (!is_type)
1752 string_delete (s);
1753 success = 0;
1754 break;
1757 if (!is_type)
1759 int len = s->p - s->b;
1760 work->tmpl_argvec[i] = xmalloc (len + 1);
1761 memcpy (work->tmpl_argvec[i], s->b, len);
1762 work->tmpl_argvec[i][len] = '\0';
1764 string_appends (tname, s);
1765 string_delete (s);
1768 need_comma = 1;
1770 if (is_java_array)
1772 string_append (tname, "[]");
1774 else
1776 if (tname->p[-1] == '>')
1777 string_append (tname, " ");
1778 string_append (tname, ">");
1781 if (is_type && remember)
1782 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1785 if (work -> static_type)
1787 string_append (declp, *mangled + 1);
1788 *mangled += strlen (*mangled);
1789 success = 1;
1791 else
1793 success = demangle_args (work, mangled, declp);
1797 return (success);
1800 static int
1801 arm_pt (work, mangled, n, anchor, args)
1802 struct work_stuff *work;
1803 const char *mangled;
1804 int n;
1805 const char **anchor, **args;
1807 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1808 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1809 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1811 int len;
1812 *args = *anchor + 6;
1813 len = consume_count (args);
1814 if (len == -1)
1815 return 0;
1816 if (*args + len == mangled + n && **args == '_')
1818 ++*args;
1819 return 1;
1822 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1824 if ((*anchor = mystrstr (mangled, "__tm__"))
1825 || (*anchor = mystrstr (mangled, "__ps__"))
1826 || (*anchor = mystrstr (mangled, "__pt__")))
1828 int len;
1829 *args = *anchor + 6;
1830 len = consume_count (args);
1831 if (len == -1)
1832 return 0;
1833 if (*args + len == mangled + n && **args == '_')
1835 ++*args;
1836 return 1;
1839 else if ((*anchor = mystrstr (mangled, "__S")))
1841 int len;
1842 *args = *anchor + 3;
1843 len = consume_count (args);
1844 if (len == -1)
1845 return 0;
1846 if (*args + len == mangled + n && **args == '_')
1848 ++*args;
1849 return 1;
1854 return 0;
1857 static void
1858 demangle_arm_hp_template (work, mangled, n, declp)
1859 struct work_stuff *work;
1860 const char **mangled;
1861 int n;
1862 string *declp;
1864 const char *p;
1865 const char *args;
1866 const char *e = *mangled + n;
1867 string arg;
1869 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1870 template args */
1871 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1873 char *start_spec_args = NULL;
1875 /* First check for and omit template specialization pseudo-arguments,
1876 such as in "Spec<#1,#1.*>" */
1877 start_spec_args = strchr (*mangled, '<');
1878 if (start_spec_args && (start_spec_args - *mangled < n))
1879 string_appendn (declp, *mangled, start_spec_args - *mangled);
1880 else
1881 string_appendn (declp, *mangled, n);
1882 (*mangled) += n + 1;
1883 string_init (&arg);
1884 if (work->temp_start == -1) /* non-recursive call */
1885 work->temp_start = declp->p - declp->b;
1886 string_append (declp, "<");
1887 while (1)
1889 string_clear (&arg);
1890 switch (**mangled)
1892 case 'T':
1893 /* 'T' signals a type parameter */
1894 (*mangled)++;
1895 if (!do_type (work, mangled, &arg))
1896 goto hpacc_template_args_done;
1897 break;
1899 case 'U':
1900 case 'S':
1901 /* 'U' or 'S' signals an integral value */
1902 if (!do_hpacc_template_const_value (work, mangled, &arg))
1903 goto hpacc_template_args_done;
1904 break;
1906 case 'A':
1907 /* 'A' signals a named constant expression (literal) */
1908 if (!do_hpacc_template_literal (work, mangled, &arg))
1909 goto hpacc_template_args_done;
1910 break;
1912 default:
1913 /* Today, 1997-09-03, we have only the above types
1914 of template parameters */
1915 /* FIXME: maybe this should fail and return null */
1916 goto hpacc_template_args_done;
1918 string_appends (declp, &arg);
1919 /* Check if we're at the end of template args.
1920 0 if at end of static member of template class,
1921 _ if done with template args for a function */
1922 if ((**mangled == '\000') || (**mangled == '_'))
1923 break;
1924 else
1925 string_append (declp, ",");
1927 hpacc_template_args_done:
1928 string_append (declp, ">");
1929 string_delete (&arg);
1930 if (**mangled == '_')
1931 (*mangled)++;
1932 return;
1934 /* ARM template? (Also handles HP cfront extensions) */
1935 else if (arm_pt (work, *mangled, n, &p, &args))
1937 string type_str;
1939 string_init (&arg);
1940 string_appendn (declp, *mangled, p - *mangled);
1941 if (work->temp_start == -1) /* non-recursive call */
1942 work->temp_start = declp->p - declp->b;
1943 string_append (declp, "<");
1944 /* should do error checking here */
1945 while (args < e) {
1946 string_clear (&arg);
1948 /* Check for type or literal here */
1949 switch (*args)
1951 /* HP cfront extensions to ARM for template args */
1952 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1953 /* FIXME: We handle only numeric literals for HP cfront */
1954 case 'X':
1955 /* A typed constant value follows */
1956 args++;
1957 if (!do_type (work, &args, &type_str))
1958 goto cfront_template_args_done;
1959 string_append (&arg, "(");
1960 string_appends (&arg, &type_str);
1961 string_append (&arg, ")");
1962 if (*args != 'L')
1963 goto cfront_template_args_done;
1964 args++;
1965 /* Now snarf a literal value following 'L' */
1966 if (!snarf_numeric_literal (&args, &arg))
1967 goto cfront_template_args_done;
1968 break;
1970 case 'L':
1971 /* Snarf a literal following 'L' */
1972 args++;
1973 if (!snarf_numeric_literal (&args, &arg))
1974 goto cfront_template_args_done;
1975 break;
1976 default:
1977 /* Not handling other HP cfront stuff */
1978 if (!do_type (work, &args, &arg))
1979 goto cfront_template_args_done;
1981 string_appends (declp, &arg);
1982 string_append (declp, ",");
1984 cfront_template_args_done:
1985 string_delete (&arg);
1986 if (args >= e)
1987 --declp->p; /* remove extra comma */
1988 string_append (declp, ">");
1990 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1991 && (*mangled)[9] == 'N'
1992 && (*mangled)[8] == (*mangled)[10]
1993 && strchr (cplus_markers, (*mangled)[8]))
1995 /* A member of the anonymous namespace. */
1996 string_append (declp, "{anonymous}");
1998 else
2000 if (work->temp_start == -1) /* non-recursive call only */
2001 work->temp_start = 0; /* disable in recursive calls */
2002 string_appendn (declp, *mangled, n);
2004 *mangled += n;
2007 /* Extract a class name, possibly a template with arguments, from the
2008 mangled string; qualifiers, local class indicators, etc. have
2009 already been dealt with */
2011 static int
2012 demangle_class_name (work, mangled, declp)
2013 struct work_stuff *work;
2014 const char **mangled;
2015 string *declp;
2017 int n;
2018 int success = 0;
2020 n = consume_count (mangled);
2021 if (n == -1)
2022 return 0;
2023 if ((int) strlen (*mangled) >= n)
2025 demangle_arm_hp_template (work, mangled, n, declp);
2026 success = 1;
2029 return (success);
2034 LOCAL FUNCTION
2036 demangle_class -- demangle a mangled class sequence
2038 SYNOPSIS
2040 static int
2041 demangle_class (struct work_stuff *work, const char **mangled,
2042 strint *declp)
2044 DESCRIPTION
2046 DECLP points to the buffer into which demangling is being done.
2048 *MANGLED points to the current token to be demangled. On input,
2049 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2050 On exit, it points to the next token after the mangled class on
2051 success, or the first unconsumed token on failure.
2053 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2054 we are demangling a constructor or destructor. In this case
2055 we prepend "class::class" or "class::~class" to DECLP.
2057 Otherwise, we prepend "class::" to the current DECLP.
2059 Reset the constructor/destructor flags once they have been
2060 "consumed". This allows demangle_class to be called later during
2061 the same demangling, to do normal class demangling.
2063 Returns 1 if demangling is successful, 0 otherwise.
2067 static int
2068 demangle_class (work, mangled, declp)
2069 struct work_stuff *work;
2070 const char **mangled;
2071 string *declp;
2073 int success = 0;
2074 int btype;
2075 string class_name;
2076 char *save_class_name_end = 0;
2078 string_init (&class_name);
2079 btype = register_Btype (work);
2080 if (demangle_class_name (work, mangled, &class_name))
2082 save_class_name_end = class_name.p;
2083 if ((work->constructor & 1) || (work->destructor & 1))
2085 /* adjust so we don't include template args */
2086 if (work->temp_start && (work->temp_start != -1))
2088 class_name.p = class_name.b + work->temp_start;
2090 string_prepends (declp, &class_name);
2091 if (work -> destructor & 1)
2093 string_prepend (declp, "~");
2094 work -> destructor -= 1;
2096 else
2098 work -> constructor -= 1;
2101 class_name.p = save_class_name_end;
2102 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2103 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2104 string_prepend (declp, SCOPE_STRING (work));
2105 string_prepends (declp, &class_name);
2106 success = 1;
2108 string_delete (&class_name);
2109 return (success);
2114 LOCAL FUNCTION
2116 demangle_prefix -- consume the mangled name prefix and find signature
2118 SYNOPSIS
2120 static int
2121 demangle_prefix (struct work_stuff *work, const char **mangled,
2122 string *declp);
2124 DESCRIPTION
2126 Consume and demangle the prefix of the mangled name.
2128 DECLP points to the string buffer into which demangled output is
2129 placed. On entry, the buffer is empty. On exit it contains
2130 the root function name, the demangled operator name, or in some
2131 special cases either nothing or the completely demangled result.
2133 MANGLED points to the current pointer into the mangled name. As each
2134 token of the mangled name is consumed, it is updated. Upon entry
2135 the current mangled name pointer points to the first character of
2136 the mangled name. Upon exit, it should point to the first character
2137 of the signature if demangling was successful, or to the first
2138 unconsumed character if demangling of the prefix was unsuccessful.
2140 Returns 1 on success, 0 otherwise.
2143 static int
2144 demangle_prefix (work, mangled, declp)
2145 struct work_stuff *work;
2146 const char **mangled;
2147 string *declp;
2149 int success = 1;
2150 const char *scan;
2151 int i;
2153 if (strlen(*mangled) > 6
2154 && (strncmp(*mangled, "_imp__", 6) == 0
2155 || strncmp(*mangled, "__imp_", 6) == 0))
2157 /* it's a symbol imported from a PE dynamic library. Check for both
2158 new style prefix _imp__ and legacy __imp_ used by older versions
2159 of dlltool. */
2160 (*mangled) += 6;
2161 work->dllimported = 1;
2163 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2165 char *marker = strchr (cplus_markers, (*mangled)[8]);
2166 if (marker != NULL && *marker == (*mangled)[10])
2168 if ((*mangled)[9] == 'D')
2170 /* it's a GNU global destructor to be executed at program exit */
2171 (*mangled) += 11;
2172 work->destructor = 2;
2173 if (gnu_special (work, mangled, declp))
2174 return success;
2176 else if ((*mangled)[9] == 'I')
2178 /* it's a GNU global constructor to be executed at program init */
2179 (*mangled) += 11;
2180 work->constructor = 2;
2181 if (gnu_special (work, mangled, declp))
2182 return success;
2186 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2188 /* it's a ARM global destructor to be executed at program exit */
2189 (*mangled) += 7;
2190 work->destructor = 2;
2192 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2194 /* it's a ARM global constructor to be executed at program initial */
2195 (*mangled) += 7;
2196 work->constructor = 2;
2199 /* This block of code is a reduction in strength time optimization
2201 scan = mystrstr (*mangled, "__"); */
2204 scan = *mangled;
2206 do {
2207 scan = strchr (scan, '_');
2208 } while (scan != NULL && *++scan != '_');
2210 if (scan != NULL) --scan;
2213 if (scan != NULL)
2215 /* We found a sequence of two or more '_', ensure that we start at
2216 the last pair in the sequence. */
2217 i = strspn (scan, "_");
2218 if (i > 2)
2220 scan += (i - 2);
2224 if (scan == NULL)
2226 success = 0;
2228 else if (work -> static_type)
2230 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2232 success = 0;
2235 else if ((scan == *mangled)
2236 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2237 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2239 /* The ARM says nothing about the mangling of local variables.
2240 But cfront mangles local variables by prepending __<nesting_level>
2241 to them. As an extension to ARM demangling we handle this case. */
2242 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2243 && isdigit ((unsigned char)scan[2]))
2245 *mangled = scan + 2;
2246 consume_count (mangled);
2247 string_append (declp, *mangled);
2248 *mangled += strlen (*mangled);
2249 success = 1;
2251 else
2253 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2254 names like __Q2_3foo3bar for nested type names. So don't accept
2255 this style of constructor for cfront demangling. A GNU
2256 style member-template constructor starts with 'H'. */
2257 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2258 work -> constructor += 1;
2259 *mangled = scan + 2;
2262 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2264 /* Cfront-style parameterized type. Handled later as a signature. */
2265 success = 1;
2267 /* ARM template? */
2268 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2270 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2271 || (scan[2] == 'p' && scan[3] == 's')
2272 || (scan[2] == 'p' && scan[3] == 't')))
2274 /* EDG-style parameterized type. Handled later as a signature. */
2275 success = 1;
2277 /* EDG template? */
2278 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2280 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2281 && (scan[2] != 't'))
2283 /* Mangled name starts with "__". Skip over any leading '_' characters,
2284 then find the next "__" that separates the prefix from the signature.
2286 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2287 || (arm_special (mangled, declp) == 0))
2289 while (*scan == '_')
2291 scan++;
2293 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2295 /* No separator (I.E. "__not_mangled"), or empty signature
2296 (I.E. "__not_mangled_either__") */
2297 success = 0;
2299 else
2301 const char *tmp;
2303 /* Look for the LAST occurrence of __, allowing names to
2304 have the '__' sequence embedded in them. */
2305 if (!(ARM_DEMANGLING || HP_DEMANGLING))
2307 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
2308 scan = tmp;
2310 if (*(scan + 2) == '\0')
2311 success = 0;
2312 else
2313 demangle_function_name (work, mangled, declp, scan);
2317 else if (*(scan + 2) != '\0')
2319 /* Mangled name does not start with "__" but does have one somewhere
2320 in there with non empty stuff after it. Looks like a global
2321 function name. */
2322 demangle_function_name (work, mangled, declp, scan);
2324 else
2326 /* Doesn't look like a mangled name */
2327 success = 0;
2330 if (!success && (work->constructor == 2 || work->destructor == 2))
2332 string_append (declp, *mangled);
2333 *mangled += strlen (*mangled);
2334 success = 1;
2336 return (success);
2341 LOCAL FUNCTION
2343 gnu_special -- special handling of gnu mangled strings
2345 SYNOPSIS
2347 static int
2348 gnu_special (struct work_stuff *work, const char **mangled,
2349 string *declp);
2352 DESCRIPTION
2354 Process some special GNU style mangling forms that don't fit
2355 the normal pattern. For example:
2357 _$_3foo (destructor for class foo)
2358 _vt$foo (foo virtual table)
2359 _vt$foo$bar (foo::bar virtual table)
2360 __vt_foo (foo virtual table, new style with thunks)
2361 _3foo$varname (static data member)
2362 _Q22rs2tu$vw (static data member)
2363 __t6vector1Zii (constructor with template)
2364 __thunk_4__$_7ostream (virtual function thunk)
2367 static int
2368 gnu_special (work, mangled, declp)
2369 struct work_stuff *work;
2370 const char **mangled;
2371 string *declp;
2373 int n;
2374 int success = 1;
2375 const char *p;
2377 if ((*mangled)[0] == '_'
2378 && strchr (cplus_markers, (*mangled)[1]) != NULL
2379 && (*mangled)[2] == '_')
2381 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2382 (*mangled) += 3;
2383 work -> destructor += 1;
2385 else if ((*mangled)[0] == '_'
2386 && (((*mangled)[1] == '_'
2387 && (*mangled)[2] == 'v'
2388 && (*mangled)[3] == 't'
2389 && (*mangled)[4] == '_')
2390 || ((*mangled)[1] == 'v'
2391 && (*mangled)[2] == 't'
2392 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2394 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2395 and create the decl. Note that we consume the entire mangled
2396 input string, which means that demangle_signature has no work
2397 to do. */
2398 if ((*mangled)[2] == 'v')
2399 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2400 else
2401 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2402 while (**mangled != '\0')
2404 switch (**mangled)
2406 case 'Q':
2407 case 'K':
2408 success = demangle_qualified (work, mangled, declp, 0, 1);
2409 break;
2410 case 't':
2411 success = demangle_template (work, mangled, declp, 0, 1,
2413 break;
2414 default:
2415 if (isdigit((unsigned char)*mangled[0]))
2417 n = consume_count(mangled);
2418 /* We may be seeing a too-large size, or else a
2419 ".<digits>" indicating a static local symbol. In
2420 any case, declare victory and move on; *don't* try
2421 to use n to allocate. */
2422 if (n > (int) strlen (*mangled))
2424 success = 1;
2425 break;
2428 else
2430 n = strcspn (*mangled, cplus_markers);
2432 string_appendn (declp, *mangled, n);
2433 (*mangled) += n;
2436 p = strpbrk (*mangled, cplus_markers);
2437 if (success && ((p == NULL) || (p == *mangled)))
2439 if (p != NULL)
2441 string_append (declp, SCOPE_STRING (work));
2442 (*mangled)++;
2445 else
2447 success = 0;
2448 break;
2451 if (success)
2452 string_append (declp, " virtual table");
2454 else if ((*mangled)[0] == '_'
2455 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2456 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2458 /* static data member, "_3foo$varname" for example */
2459 (*mangled)++;
2460 switch (**mangled)
2462 case 'Q':
2463 case 'K':
2464 success = demangle_qualified (work, mangled, declp, 0, 1);
2465 break;
2466 case 't':
2467 success = demangle_template (work, mangled, declp, 0, 1, 1);
2468 break;
2469 default:
2470 n = consume_count (mangled);
2471 if (n < 0 || n > (long) strlen (*mangled))
2473 success = 0;
2474 break;
2476 string_appendn (declp, *mangled, n);
2477 (*mangled) += n;
2479 if (success && (p == *mangled))
2481 /* Consumed everything up to the cplus_marker, append the
2482 variable name. */
2483 (*mangled)++;
2484 string_append (declp, SCOPE_STRING (work));
2485 n = strlen (*mangled);
2486 string_appendn (declp, *mangled, n);
2487 (*mangled) += n;
2489 else
2491 success = 0;
2494 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2496 int delta;
2498 (*mangled) += 8;
2499 delta = consume_count (mangled);
2500 if (delta == -1)
2501 success = 0;
2502 else
2504 char *method = internal_cplus_demangle (work, ++*mangled);
2506 if (method)
2508 char buf[50];
2509 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2510 string_append (declp, buf);
2511 string_append (declp, method);
2512 free (method);
2513 n = strlen (*mangled);
2514 (*mangled) += n;
2516 else
2518 success = 0;
2522 else if (strncmp (*mangled, "__t", 3) == 0
2523 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2525 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2526 (*mangled) += 4;
2527 switch (**mangled)
2529 case 'Q':
2530 case 'K':
2531 success = demangle_qualified (work, mangled, declp, 0, 1);
2532 break;
2533 case 't':
2534 success = demangle_template (work, mangled, declp, 0, 1, 1);
2535 break;
2536 default:
2537 success = demangle_fund_type (work, mangled, declp);
2538 break;
2540 if (success && **mangled != '\0')
2541 success = 0;
2542 if (success)
2543 string_append (declp, p);
2545 else
2547 success = 0;
2549 return (success);
2552 static void
2553 recursively_demangle(work, mangled, result, namelength)
2554 struct work_stuff *work;
2555 const char **mangled;
2556 string *result;
2557 int namelength;
2559 char * recurse = (char *)NULL;
2560 char * recurse_dem = (char *)NULL;
2562 recurse = (char *) xmalloc (namelength + 1);
2563 memcpy (recurse, *mangled, namelength);
2564 recurse[namelength] = '\000';
2566 recurse_dem = cplus_demangle (recurse, work->options);
2568 if (recurse_dem)
2570 string_append (result, recurse_dem);
2571 free (recurse_dem);
2573 else
2575 string_appendn (result, *mangled, namelength);
2577 free (recurse);
2578 *mangled += namelength;
2583 LOCAL FUNCTION
2585 arm_special -- special handling of ARM/lucid mangled strings
2587 SYNOPSIS
2589 static int
2590 arm_special (const char **mangled,
2591 string *declp);
2594 DESCRIPTION
2596 Process some special ARM style mangling forms that don't fit
2597 the normal pattern. For example:
2599 __vtbl__3foo (foo virtual table)
2600 __vtbl__3foo__3bar (bar::foo virtual table)
2604 static int
2605 arm_special (mangled, declp)
2606 const char **mangled;
2607 string *declp;
2609 int n;
2610 int success = 1;
2611 const char *scan;
2613 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2615 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2616 and create the decl. Note that we consume the entire mangled
2617 input string, which means that demangle_signature has no work
2618 to do. */
2619 scan = *mangled + ARM_VTABLE_STRLEN;
2620 while (*scan != '\0') /* first check it can be demangled */
2622 n = consume_count (&scan);
2623 if (n == -1)
2625 return (0); /* no good */
2627 scan += n;
2628 if (scan[0] == '_' && scan[1] == '_')
2630 scan += 2;
2633 (*mangled) += ARM_VTABLE_STRLEN;
2634 while (**mangled != '\0')
2636 n = consume_count (mangled);
2637 if (n == -1
2638 || n > (long) strlen (*mangled))
2639 return 0;
2640 string_prependn (declp, *mangled, n);
2641 (*mangled) += n;
2642 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2644 string_prepend (declp, "::");
2645 (*mangled) += 2;
2648 string_append (declp, " virtual table");
2650 else
2652 success = 0;
2654 return (success);
2659 LOCAL FUNCTION
2661 demangle_qualified -- demangle 'Q' qualified name strings
2663 SYNOPSIS
2665 static int
2666 demangle_qualified (struct work_stuff *, const char *mangled,
2667 string *result, int isfuncname, int append);
2669 DESCRIPTION
2671 Demangle a qualified name, such as "Q25Outer5Inner" which is
2672 the mangled form of "Outer::Inner". The demangled output is
2673 prepended or appended to the result string according to the
2674 state of the append flag.
2676 If isfuncname is nonzero, then the qualified name we are building
2677 is going to be used as a member function name, so if it is a
2678 constructor or destructor function, append an appropriate
2679 constructor or destructor name. I.E. for the above example,
2680 the result for use as a constructor is "Outer::Inner::Inner"
2681 and the result for use as a destructor is "Outer::Inner::~Inner".
2683 BUGS
2685 Numeric conversion is ASCII dependent (FIXME).
2689 static int
2690 demangle_qualified (work, mangled, result, isfuncname, append)
2691 struct work_stuff *work;
2692 const char **mangled;
2693 string *result;
2694 int isfuncname;
2695 int append;
2697 int qualifiers = 0;
2698 int success = 1;
2699 const char *p;
2700 char num[2];
2701 string temp;
2702 string last_name;
2703 int bindex = register_Btype (work);
2705 /* We only make use of ISFUNCNAME if the entity is a constructor or
2706 destructor. */
2707 isfuncname = (isfuncname
2708 && ((work->constructor & 1) || (work->destructor & 1)));
2710 string_init (&temp);
2711 string_init (&last_name);
2713 if ((*mangled)[0] == 'K')
2715 /* Squangling qualified name reuse */
2716 int idx;
2717 (*mangled)++;
2718 idx = consume_count_with_underscores (mangled);
2719 if (idx == -1 || idx >= work -> numk)
2720 success = 0;
2721 else
2722 string_append (&temp, work -> ktypevec[idx]);
2724 else
2725 switch ((*mangled)[1])
2727 case '_':
2728 /* GNU mangled name with more than 9 classes. The count is preceded
2729 by an underscore (to distinguish it from the <= 9 case) and followed
2730 by an underscore. */
2731 p = *mangled + 2;
2732 qualifiers = atoi (p);
2733 if (!isdigit ((unsigned char)*p) || *p == '0')
2734 success = 0;
2736 /* Skip the digits. */
2737 while (isdigit ((unsigned char)*p))
2738 ++p;
2740 if (*p != '_')
2741 success = 0;
2743 *mangled = p + 1;
2744 break;
2746 case '1':
2747 case '2':
2748 case '3':
2749 case '4':
2750 case '5':
2751 case '6':
2752 case '7':
2753 case '8':
2754 case '9':
2755 /* The count is in a single digit. */
2756 num[0] = (*mangled)[1];
2757 num[1] = '\0';
2758 qualifiers = atoi (num);
2760 /* If there is an underscore after the digit, skip it. This is
2761 said to be for ARM-qualified names, but the ARM makes no
2762 mention of such an underscore. Perhaps cfront uses one. */
2763 if ((*mangled)[2] == '_')
2765 (*mangled)++;
2767 (*mangled) += 2;
2768 break;
2770 case '0':
2771 default:
2772 success = 0;
2775 if (!success)
2776 return success;
2778 /* Pick off the names and collect them in the temp buffer in the order
2779 in which they are found, separated by '::'. */
2781 while (qualifiers-- > 0)
2783 int remember_K = 1;
2784 string_clear (&last_name);
2786 if (*mangled[0] == '_')
2787 (*mangled)++;
2789 if (*mangled[0] == 't')
2791 /* Here we always append to TEMP since we will want to use
2792 the template name without the template parameters as a
2793 constructor or destructor name. The appropriate
2794 (parameter-less) value is returned by demangle_template
2795 in LAST_NAME. We do not remember the template type here,
2796 in order to match the G++ mangling algorithm. */
2797 success = demangle_template(work, mangled, &temp,
2798 &last_name, 1, 0);
2799 if (!success)
2800 break;
2802 else if (*mangled[0] == 'K')
2804 int idx;
2805 (*mangled)++;
2806 idx = consume_count_with_underscores (mangled);
2807 if (idx == -1 || idx >= work->numk)
2808 success = 0;
2809 else
2810 string_append (&temp, work->ktypevec[idx]);
2811 remember_K = 0;
2813 if (!success) break;
2815 else
2817 if (EDG_DEMANGLING)
2819 int namelength;
2820 /* Now recursively demangle the qualifier
2821 * This is necessary to deal with templates in
2822 * mangling styles like EDG */
2823 namelength = consume_count (mangled);
2824 if (namelength == -1)
2826 success = 0;
2827 break;
2829 recursively_demangle(work, mangled, &temp, namelength);
2831 else
2833 success = do_type (work, mangled, &last_name);
2834 if (!success)
2835 break;
2836 string_appends (&temp, &last_name);
2840 if (remember_K)
2841 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2843 if (qualifiers > 0)
2844 string_append (&temp, SCOPE_STRING (work));
2847 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2849 /* If we are using the result as a function name, we need to append
2850 the appropriate '::' separated constructor or destructor name.
2851 We do this here because this is the most convenient place, where
2852 we already have a pointer to the name and the length of the name. */
2854 if (isfuncname)
2856 string_append (&temp, SCOPE_STRING (work));
2857 if (work -> destructor & 1)
2858 string_append (&temp, "~");
2859 string_appends (&temp, &last_name);
2862 /* Now either prepend the temp buffer to the result, or append it,
2863 depending upon the state of the append flag. */
2865 if (append)
2866 string_appends (result, &temp);
2867 else
2869 if (!STRING_EMPTY (result))
2870 string_append (&temp, SCOPE_STRING (work));
2871 string_prepends (result, &temp);
2874 string_delete (&last_name);
2875 string_delete (&temp);
2876 return (success);
2881 LOCAL FUNCTION
2883 get_count -- convert an ascii count to integer, consuming tokens
2885 SYNOPSIS
2887 static int
2888 get_count (const char **type, int *count)
2890 DESCRIPTION
2892 Assume that *type points at a count in a mangled name; set
2893 *count to its value, and set *type to the next character after
2894 the count. There are some weird rules in effect here.
2896 If *type does not point at a string of digits, return zero.
2898 If *type points at a string of digits followed by an
2899 underscore, set *count to their value as an integer, advance
2900 *type to point *after the underscore, and return 1.
2902 If *type points at a string of digits not followed by an
2903 underscore, consume only the first digit. Set *count to its
2904 value as an integer, leave *type pointing after that digit,
2905 and return 1.
2907 The excuse for this odd behavior: in the ARM and HP demangling
2908 styles, a type can be followed by a repeat count of the form
2909 `Nxy', where:
2911 `x' is a single digit specifying how many additional copies
2912 of the type to append to the argument list, and
2914 `y' is one or more digits, specifying the zero-based index of
2915 the first repeated argument in the list. Yes, as you're
2916 unmangling the name you can figure this out yourself, but
2917 it's there anyway.
2919 So, for example, in `bar__3fooFPiN51', the first argument is a
2920 pointer to an integer (`Pi'), and then the next five arguments
2921 are the same (`N5'), and the first repeat is the function's
2922 second argument (`1').
2925 static int
2926 get_count (type, count)
2927 const char **type;
2928 int *count;
2930 const char *p;
2931 int n;
2933 if (!isdigit ((unsigned char)**type))
2935 return (0);
2937 else
2939 *count = **type - '0';
2940 (*type)++;
2941 if (isdigit ((unsigned char)**type))
2943 p = *type;
2944 n = *count;
2947 n *= 10;
2948 n += *p - '0';
2949 p++;
2951 while (isdigit ((unsigned char)*p));
2952 if (*p == '_')
2954 *type = p + 1;
2955 *count = n;
2959 return (1);
2962 /* RESULT will be initialised here; it will be freed on failure. The
2963 value returned is really a type_kind_t. */
2965 static int
2966 do_type (work, mangled, result)
2967 struct work_stuff *work;
2968 const char **mangled;
2969 string *result;
2971 int n;
2972 int done;
2973 int success;
2974 string decl;
2975 const char *remembered_type;
2976 int type_quals;
2977 string btype;
2978 type_kind_t tk = tk_none;
2980 string_init (&btype);
2981 string_init (&decl);
2982 string_init (result);
2984 done = 0;
2985 success = 1;
2986 while (success && !done)
2988 int member;
2989 switch (**mangled)
2992 /* A pointer type */
2993 case 'P':
2994 case 'p':
2995 (*mangled)++;
2996 if (! (work -> options & DMGL_JAVA))
2997 string_prepend (&decl, "*");
2998 if (tk == tk_none)
2999 tk = tk_pointer;
3000 break;
3002 /* A reference type */
3003 case 'R':
3004 (*mangled)++;
3005 string_prepend (&decl, "&");
3006 if (tk == tk_none)
3007 tk = tk_reference;
3008 break;
3010 /* An array */
3011 case 'A':
3013 ++(*mangled);
3014 if (!STRING_EMPTY (&decl)
3015 && (decl.b[0] == '*' || decl.b[0] == '&'))
3017 string_prepend (&decl, "(");
3018 string_append (&decl, ")");
3020 string_append (&decl, "[");
3021 if (**mangled != '_')
3022 success = demangle_template_value_parm (work, mangled, &decl,
3023 tk_integral);
3024 if (**mangled == '_')
3025 ++(*mangled);
3026 string_append (&decl, "]");
3027 break;
3030 /* A back reference to a previously seen type */
3031 case 'T':
3032 (*mangled)++;
3033 if (!get_count (mangled, &n) || n >= work -> ntypes)
3035 success = 0;
3037 else
3039 remembered_type = work -> typevec[n];
3040 mangled = &remembered_type;
3042 break;
3044 /* A function */
3045 case 'F':
3046 (*mangled)++;
3047 if (!STRING_EMPTY (&decl)
3048 && (decl.b[0] == '*' || decl.b[0] == '&'))
3050 string_prepend (&decl, "(");
3051 string_append (&decl, ")");
3053 /* After picking off the function args, we expect to either find the
3054 function return type (preceded by an '_') or the end of the
3055 string. */
3056 if (!demangle_nested_args (work, mangled, &decl)
3057 || (**mangled != '_' && **mangled != '\0'))
3059 success = 0;
3060 break;
3062 if (success && (**mangled == '_'))
3063 (*mangled)++;
3064 break;
3066 case 'M':
3067 case 'O':
3069 type_quals = TYPE_UNQUALIFIED;
3071 member = **mangled == 'M';
3072 (*mangled)++;
3074 string_append (&decl, ")");
3076 /* We don't need to prepend `::' for a qualified name;
3077 demangle_qualified will do that for us. */
3078 if (**mangled != 'Q')
3079 string_prepend (&decl, SCOPE_STRING (work));
3081 if (isdigit ((unsigned char)**mangled))
3083 n = consume_count (mangled);
3084 if (n == -1
3085 || (int) strlen (*mangled) < n)
3087 success = 0;
3088 break;
3090 string_prependn (&decl, *mangled, n);
3091 *mangled += n;
3093 else if (**mangled == 'X' || **mangled == 'Y')
3095 string temp;
3096 do_type (work, mangled, &temp);
3097 string_prepends (&decl, &temp);
3099 else if (**mangled == 't')
3101 string temp;
3102 string_init (&temp);
3103 success = demangle_template (work, mangled, &temp,
3104 NULL, 1, 1);
3105 if (success)
3107 string_prependn (&decl, temp.b, temp.p - temp.b);
3108 string_clear (&temp);
3110 else
3111 break;
3113 else if (**mangled == 'Q')
3115 success = demangle_qualified (work, mangled, &decl,
3116 /*isfuncnam=*/0,
3117 /*append=*/0);
3118 if (!success)
3119 break;
3121 else
3123 success = 0;
3124 break;
3127 string_prepend (&decl, "(");
3128 if (member)
3130 switch (**mangled)
3132 case 'C':
3133 case 'V':
3134 case 'u':
3135 type_quals |= code_for_qualifier (**mangled);
3136 (*mangled)++;
3137 break;
3139 default:
3140 break;
3143 if (*(*mangled)++ != 'F')
3145 success = 0;
3146 break;
3149 if ((member && !demangle_nested_args (work, mangled, &decl))
3150 || **mangled != '_')
3152 success = 0;
3153 break;
3155 (*mangled)++;
3156 if (! PRINT_ANSI_QUALIFIERS)
3158 break;
3160 if (type_quals != TYPE_UNQUALIFIED)
3162 APPEND_BLANK (&decl);
3163 string_append (&decl, qualifier_string (type_quals));
3165 break;
3167 case 'G':
3168 (*mangled)++;
3169 break;
3171 case 'C':
3172 case 'V':
3173 case 'u':
3174 if (PRINT_ANSI_QUALIFIERS)
3176 if (!STRING_EMPTY (&decl))
3177 string_prepend (&decl, " ");
3179 string_prepend (&decl, demangle_qualifier (**mangled));
3181 (*mangled)++;
3182 break;
3187 /* fall through */
3188 default:
3189 done = 1;
3190 break;
3194 if (success) switch (**mangled)
3196 /* A qualified name, such as "Outer::Inner". */
3197 case 'Q':
3198 case 'K':
3200 success = demangle_qualified (work, mangled, result, 0, 1);
3201 break;
3204 /* A back reference to a previously seen squangled type */
3205 case 'B':
3206 (*mangled)++;
3207 if (!get_count (mangled, &n) || n >= work -> numb)
3208 success = 0;
3209 else
3210 string_append (result, work->btypevec[n]);
3211 break;
3213 case 'X':
3214 case 'Y':
3215 /* A template parm. We substitute the corresponding argument. */
3217 int idx;
3219 (*mangled)++;
3220 idx = consume_count_with_underscores (mangled);
3222 if (idx == -1
3223 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3224 || consume_count_with_underscores (mangled) == -1)
3226 success = 0;
3227 break;
3230 if (work->tmpl_argvec)
3231 string_append (result, work->tmpl_argvec[idx]);
3232 else
3234 char buf[10];
3235 sprintf(buf, "T%d", idx);
3236 string_append (result, buf);
3239 success = 1;
3241 break;
3243 default:
3244 success = demangle_fund_type (work, mangled, result);
3245 if (tk == tk_none)
3246 tk = (type_kind_t) success;
3247 break;
3250 if (success)
3252 if (!STRING_EMPTY (&decl))
3254 string_append (result, " ");
3255 string_appends (result, &decl);
3258 else
3259 string_delete (result);
3260 string_delete (&decl);
3262 if (success)
3263 /* Assume an integral type, if we're not sure. */
3264 return (int) ((tk == tk_none) ? tk_integral : tk);
3265 else
3266 return 0;
3269 /* Given a pointer to a type string that represents a fundamental type
3270 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3271 string in which the demangled output is being built in RESULT, and
3272 the WORK structure, decode the types and add them to the result.
3274 For example:
3276 "Ci" => "const int"
3277 "Sl" => "signed long"
3278 "CUs" => "const unsigned short"
3280 The value returned is really a type_kind_t. */
3282 static int
3283 demangle_fund_type (work, mangled, result)
3284 struct work_stuff *work;
3285 const char **mangled;
3286 string *result;
3288 int done = 0;
3289 int success = 1;
3290 char buf[10];
3291 int dec = 0;
3292 string btype;
3293 type_kind_t tk = tk_integral;
3295 string_init (&btype);
3297 /* First pick off any type qualifiers. There can be more than one. */
3299 while (!done)
3301 switch (**mangled)
3303 case 'C':
3304 case 'V':
3305 case 'u':
3306 if (PRINT_ANSI_QUALIFIERS)
3308 if (!STRING_EMPTY (result))
3309 string_prepend (result, " ");
3310 string_prepend (result, demangle_qualifier (**mangled));
3312 (*mangled)++;
3313 break;
3314 case 'U':
3315 (*mangled)++;
3316 APPEND_BLANK (result);
3317 string_append (result, "unsigned");
3318 break;
3319 case 'S': /* signed char only */
3320 (*mangled)++;
3321 APPEND_BLANK (result);
3322 string_append (result, "signed");
3323 break;
3324 case 'J':
3325 (*mangled)++;
3326 APPEND_BLANK (result);
3327 string_append (result, "__complex");
3328 break;
3329 default:
3330 done = 1;
3331 break;
3335 /* Now pick off the fundamental type. There can be only one. */
3337 switch (**mangled)
3339 case '\0':
3340 case '_':
3341 break;
3342 case 'v':
3343 (*mangled)++;
3344 APPEND_BLANK (result);
3345 string_append (result, "void");
3346 break;
3347 case 'x':
3348 (*mangled)++;
3349 APPEND_BLANK (result);
3350 string_append (result, "long long");
3351 break;
3352 case 'l':
3353 (*mangled)++;
3354 APPEND_BLANK (result);
3355 string_append (result, "long");
3356 break;
3357 case 'i':
3358 (*mangled)++;
3359 APPEND_BLANK (result);
3360 string_append (result, "int");
3361 break;
3362 case 's':
3363 (*mangled)++;
3364 APPEND_BLANK (result);
3365 string_append (result, "short");
3366 break;
3367 case 'b':
3368 (*mangled)++;
3369 APPEND_BLANK (result);
3370 string_append (result, "bool");
3371 tk = tk_bool;
3372 break;
3373 case 'c':
3374 (*mangled)++;
3375 APPEND_BLANK (result);
3376 string_append (result, "char");
3377 tk = tk_char;
3378 break;
3379 case 'w':
3380 (*mangled)++;
3381 APPEND_BLANK (result);
3382 string_append (result, "wchar_t");
3383 tk = tk_char;
3384 break;
3385 case 'r':
3386 (*mangled)++;
3387 APPEND_BLANK (result);
3388 string_append (result, "long double");
3389 tk = tk_real;
3390 break;
3391 case 'd':
3392 (*mangled)++;
3393 APPEND_BLANK (result);
3394 string_append (result, "double");
3395 tk = tk_real;
3396 break;
3397 case 'f':
3398 (*mangled)++;
3399 APPEND_BLANK (result);
3400 string_append (result, "float");
3401 tk = tk_real;
3402 break;
3403 case 'G':
3404 (*mangled)++;
3405 if (!isdigit ((unsigned char)**mangled))
3407 success = 0;
3408 break;
3410 case 'I':
3411 (*mangled)++;
3412 if (**mangled == '_')
3414 int i;
3415 (*mangled)++;
3416 for (i = 0;
3417 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3418 (*mangled)++, i++)
3419 buf[i] = **mangled;
3420 if (**mangled != '_')
3422 success = 0;
3423 break;
3425 buf[i] = '\0';
3426 (*mangled)++;
3428 else
3430 strncpy (buf, *mangled, 2);
3431 buf[2] = '\0';
3432 *mangled += min (strlen (*mangled), 2);
3434 sscanf (buf, "%x", &dec);
3435 sprintf (buf, "int%i_t", dec);
3436 APPEND_BLANK (result);
3437 string_append (result, buf);
3438 break;
3440 /* fall through */
3441 /* An explicit type, such as "6mytype" or "7integer" */
3442 case '0':
3443 case '1':
3444 case '2':
3445 case '3':
3446 case '4':
3447 case '5':
3448 case '6':
3449 case '7':
3450 case '8':
3451 case '9':
3453 int bindex = register_Btype (work);
3454 string btype;
3455 string_init (&btype);
3456 if (demangle_class_name (work, mangled, &btype)) {
3457 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3458 APPEND_BLANK (result);
3459 string_appends (result, &btype);
3461 else
3462 success = 0;
3463 string_delete (&btype);
3464 break;
3466 case 't':
3468 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3469 string_appends (result, &btype);
3470 break;
3472 default:
3473 success = 0;
3474 break;
3477 return success ? ((int) tk) : 0;
3481 /* Handle a template's value parameter for HP aCC (extension from ARM)
3482 **mangled points to 'S' or 'U' */
3484 static int
3485 do_hpacc_template_const_value (work, mangled, result)
3486 struct work_stuff *work ATTRIBUTE_UNUSED;
3487 const char **mangled;
3488 string *result;
3490 int unsigned_const;
3492 if (**mangled != 'U' && **mangled != 'S')
3493 return 0;
3495 unsigned_const = (**mangled == 'U');
3497 (*mangled)++;
3499 switch (**mangled)
3501 case 'N':
3502 string_append (result, "-");
3503 /* fall through */
3504 case 'P':
3505 (*mangled)++;
3506 break;
3507 case 'M':
3508 /* special case for -2^31 */
3509 string_append (result, "-2147483648");
3510 (*mangled)++;
3511 return 1;
3512 default:
3513 return 0;
3516 /* We have to be looking at an integer now */
3517 if (!(isdigit ((unsigned char)**mangled)))
3518 return 0;
3520 /* We only deal with integral values for template
3521 parameters -- so it's OK to look only for digits */
3522 while (isdigit ((unsigned char)**mangled))
3524 char_str[0] = **mangled;
3525 string_append (result, char_str);
3526 (*mangled)++;
3529 if (unsigned_const)
3530 string_append (result, "U");
3532 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3533 with L or LL suffixes. pai/1997-09-03 */
3535 return 1; /* success */
3538 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3539 **mangled is pointing to the 'A' */
3541 static int
3542 do_hpacc_template_literal (work, mangled, result)
3543 struct work_stuff *work;
3544 const char **mangled;
3545 string *result;
3547 int literal_len = 0;
3548 char * recurse;
3549 char * recurse_dem;
3551 if (**mangled != 'A')
3552 return 0;
3554 (*mangled)++;
3556 literal_len = consume_count (mangled);
3558 if (literal_len <= 0)
3559 return 0;
3561 /* Literal parameters are names of arrays, functions, etc. and the
3562 canonical representation uses the address operator */
3563 string_append (result, "&");
3565 /* Now recursively demangle the literal name */
3566 recurse = (char *) xmalloc (literal_len + 1);
3567 memcpy (recurse, *mangled, literal_len);
3568 recurse[literal_len] = '\000';
3570 recurse_dem = cplus_demangle (recurse, work->options);
3572 if (recurse_dem)
3574 string_append (result, recurse_dem);
3575 free (recurse_dem);
3577 else
3579 string_appendn (result, *mangled, literal_len);
3581 (*mangled) += literal_len;
3582 free (recurse);
3584 return 1;
3587 static int
3588 snarf_numeric_literal (args, arg)
3589 const char ** args;
3590 string * arg;
3592 if (**args == '-')
3594 char_str[0] = '-';
3595 string_append (arg, char_str);
3596 (*args)++;
3598 else if (**args == '+')
3599 (*args)++;
3601 if (!isdigit ((unsigned char)**args))
3602 return 0;
3604 while (isdigit ((unsigned char)**args))
3606 char_str[0] = **args;
3607 string_append (arg, char_str);
3608 (*args)++;
3611 return 1;
3614 /* Demangle the next argument, given by MANGLED into RESULT, which
3615 *should be an uninitialized* string. It will be initialized here,
3616 and free'd should anything go wrong. */
3618 static int
3619 do_arg (work, mangled, result)
3620 struct work_stuff *work;
3621 const char **mangled;
3622 string *result;
3624 /* Remember where we started so that we can record the type, for
3625 non-squangling type remembering. */
3626 const char *start = *mangled;
3628 string_init (result);
3630 if (work->nrepeats > 0)
3632 --work->nrepeats;
3634 if (work->previous_argument == 0)
3635 return 0;
3637 /* We want to reissue the previous type in this argument list. */
3638 string_appends (result, work->previous_argument);
3639 return 1;
3642 if (**mangled == 'n')
3644 /* A squangling-style repeat. */
3645 (*mangled)++;
3646 work->nrepeats = consume_count(mangled);
3648 if (work->nrepeats <= 0)
3649 /* This was not a repeat count after all. */
3650 return 0;
3652 if (work->nrepeats > 9)
3654 if (**mangled != '_')
3655 /* The repeat count should be followed by an '_' in this
3656 case. */
3657 return 0;
3658 else
3659 (*mangled)++;
3662 /* Now, the repeat is all set up. */
3663 return do_arg (work, mangled, result);
3666 /* Save the result in WORK->previous_argument so that we can find it
3667 if it's repeated. Note that saving START is not good enough: we
3668 do not want to add additional types to the back-referenceable
3669 type vector when processing a repeated type. */
3670 if (work->previous_argument)
3671 string_clear (work->previous_argument);
3672 else
3674 work->previous_argument = (string*) xmalloc (sizeof (string));
3675 string_init (work->previous_argument);
3678 if (!do_type (work, mangled, work->previous_argument))
3679 return 0;
3681 string_appends (result, work->previous_argument);
3683 remember_type (work, start, *mangled - start);
3684 return 1;
3687 static void
3688 remember_type (work, start, len)
3689 struct work_stuff *work;
3690 const char *start;
3691 int len;
3693 char *tem;
3695 if (work->forgetting_types)
3696 return;
3698 if (work -> ntypes >= work -> typevec_size)
3700 if (work -> typevec_size == 0)
3702 work -> typevec_size = 3;
3703 work -> typevec
3704 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3706 else
3708 work -> typevec_size *= 2;
3709 work -> typevec
3710 = (char **) xrealloc ((char *)work -> typevec,
3711 sizeof (char *) * work -> typevec_size);
3714 tem = xmalloc (len + 1);
3715 memcpy (tem, start, len);
3716 tem[len] = '\0';
3717 work -> typevec[work -> ntypes++] = tem;
3721 /* Remember a K type class qualifier. */
3722 static void
3723 remember_Ktype (work, start, len)
3724 struct work_stuff *work;
3725 const char *start;
3726 int len;
3728 char *tem;
3730 if (work -> numk >= work -> ksize)
3732 if (work -> ksize == 0)
3734 work -> ksize = 5;
3735 work -> ktypevec
3736 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3738 else
3740 work -> ksize *= 2;
3741 work -> ktypevec
3742 = (char **) xrealloc ((char *)work -> ktypevec,
3743 sizeof (char *) * work -> ksize);
3746 tem = xmalloc (len + 1);
3747 memcpy (tem, start, len);
3748 tem[len] = '\0';
3749 work -> ktypevec[work -> numk++] = tem;
3752 /* Register a B code, and get an index for it. B codes are registered
3753 as they are seen, rather than as they are completed, so map<temp<char> >
3754 registers map<temp<char> > as B0, and temp<char> as B1 */
3756 static int
3757 register_Btype (work)
3758 struct work_stuff *work;
3760 int ret;
3762 if (work -> numb >= work -> bsize)
3764 if (work -> bsize == 0)
3766 work -> bsize = 5;
3767 work -> btypevec
3768 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3770 else
3772 work -> bsize *= 2;
3773 work -> btypevec
3774 = (char **) xrealloc ((char *)work -> btypevec,
3775 sizeof (char *) * work -> bsize);
3778 ret = work -> numb++;
3779 work -> btypevec[ret] = NULL;
3780 return(ret);
3783 /* Store a value into a previously registered B code type. */
3785 static void
3786 remember_Btype (work, start, len, index)
3787 struct work_stuff *work;
3788 const char *start;
3789 int len, index;
3791 char *tem;
3793 tem = xmalloc (len + 1);
3794 memcpy (tem, start, len);
3795 tem[len] = '\0';
3796 work -> btypevec[index] = tem;
3799 /* Lose all the info related to B and K type codes. */
3800 static void
3801 forget_B_and_K_types (work)
3802 struct work_stuff *work;
3804 int i;
3806 while (work -> numk > 0)
3808 i = --(work -> numk);
3809 if (work -> ktypevec[i] != NULL)
3811 free (work -> ktypevec[i]);
3812 work -> ktypevec[i] = NULL;
3816 while (work -> numb > 0)
3818 i = --(work -> numb);
3819 if (work -> btypevec[i] != NULL)
3821 free (work -> btypevec[i]);
3822 work -> btypevec[i] = NULL;
3826 /* Forget the remembered types, but not the type vector itself. */
3828 static void
3829 forget_types (work)
3830 struct work_stuff *work;
3832 int i;
3834 while (work -> ntypes > 0)
3836 i = --(work -> ntypes);
3837 if (work -> typevec[i] != NULL)
3839 free (work -> typevec[i]);
3840 work -> typevec[i] = NULL;
3845 /* Process the argument list part of the signature, after any class spec
3846 has been consumed, as well as the first 'F' character (if any). For
3847 example:
3849 "__als__3fooRT0" => process "RT0"
3850 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3852 DECLP must be already initialised, usually non-empty. It won't be freed
3853 on failure.
3855 Note that g++ differs significantly from ARM and lucid style mangling
3856 with regards to references to previously seen types. For example, given
3857 the source fragment:
3859 class foo {
3860 public:
3861 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3864 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3865 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3867 g++ produces the names:
3869 __3fooiRT0iT2iT2
3870 foo__FiR3fooiT1iT1
3872 while lcc (and presumably other ARM style compilers as well) produces:
3874 foo__FiR3fooT1T2T1T2
3875 __ct__3fooFiR3fooT1T2T1T2
3877 Note that g++ bases its type numbers starting at zero and counts all
3878 previously seen types, while lucid/ARM bases its type numbers starting
3879 at one and only considers types after it has seen the 'F' character
3880 indicating the start of the function args. For lucid/ARM style, we
3881 account for this difference by discarding any previously seen types when
3882 we see the 'F' character, and subtracting one from the type number
3883 reference.
3887 static int
3888 demangle_args (work, mangled, declp)
3889 struct work_stuff *work;
3890 const char **mangled;
3891 string *declp;
3893 string arg;
3894 int need_comma = 0;
3895 int r;
3896 int t;
3897 const char *tem;
3898 char temptype;
3900 if (PRINT_ARG_TYPES)
3902 string_append (declp, "(");
3903 if (**mangled == '\0')
3905 string_append (declp, "void");
3909 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3910 || work->nrepeats > 0)
3912 if ((**mangled == 'N') || (**mangled == 'T'))
3914 temptype = *(*mangled)++;
3916 if (temptype == 'N')
3918 if (!get_count (mangled, &r))
3920 return (0);
3923 else
3925 r = 1;
3927 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3929 /* If we have 10 or more types we might have more than a 1 digit
3930 index so we'll have to consume the whole count here. This
3931 will lose if the next thing is a type name preceded by a
3932 count but it's impossible to demangle that case properly
3933 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3934 Pc, ...)" or "(..., type12, char *, ...)" */
3935 if ((t = consume_count(mangled)) <= 0)
3937 return (0);
3940 else
3942 if (!get_count (mangled, &t))
3944 return (0);
3947 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3949 t--;
3951 /* Validate the type index. Protect against illegal indices from
3952 malformed type strings. */
3953 if ((t < 0) || (t >= work -> ntypes))
3955 return (0);
3957 while (work->nrepeats > 0 || --r >= 0)
3959 tem = work -> typevec[t];
3960 if (need_comma && PRINT_ARG_TYPES)
3962 string_append (declp, ", ");
3964 if (!do_arg (work, &tem, &arg))
3966 return (0);
3968 if (PRINT_ARG_TYPES)
3970 string_appends (declp, &arg);
3972 string_delete (&arg);
3973 need_comma = 1;
3976 else
3978 if (need_comma && PRINT_ARG_TYPES)
3979 string_append (declp, ", ");
3980 if (!do_arg (work, mangled, &arg))
3981 return (0);
3982 if (PRINT_ARG_TYPES)
3983 string_appends (declp, &arg);
3984 string_delete (&arg);
3985 need_comma = 1;
3989 if (**mangled == 'e')
3991 (*mangled)++;
3992 if (PRINT_ARG_TYPES)
3994 if (need_comma)
3996 string_append (declp, ",");
3998 string_append (declp, "...");
4002 if (PRINT_ARG_TYPES)
4004 string_append (declp, ")");
4006 return (1);
4009 /* Like demangle_args, but for demangling the argument lists of function
4010 and method pointers or references, not top-level declarations. */
4012 static int
4013 demangle_nested_args (work, mangled, declp)
4014 struct work_stuff *work;
4015 const char **mangled;
4016 string *declp;
4018 string* saved_previous_argument;
4019 int result;
4020 int saved_nrepeats;
4022 /* The G++ name-mangling algorithm does not remember types on nested
4023 argument lists, unless -fsquangling is used, and in that case the
4024 type vector updated by remember_type is not used. So, we turn
4025 off remembering of types here. */
4026 ++work->forgetting_types;
4028 /* For the repeat codes used with -fsquangling, we must keep track of
4029 the last argument. */
4030 saved_previous_argument = work->previous_argument;
4031 saved_nrepeats = work->nrepeats;
4032 work->previous_argument = 0;
4033 work->nrepeats = 0;
4035 /* Actually demangle the arguments. */
4036 result = demangle_args (work, mangled, declp);
4038 /* Restore the previous_argument field. */
4039 if (work->previous_argument)
4040 string_delete (work->previous_argument);
4041 work->previous_argument = saved_previous_argument;
4042 --work->forgetting_types;
4043 work->nrepeats = saved_nrepeats;
4045 return result;
4048 static void
4049 demangle_function_name (work, mangled, declp, scan)
4050 struct work_stuff *work;
4051 const char **mangled;
4052 string *declp;
4053 const char *scan;
4055 size_t i;
4056 string type;
4057 const char *tem;
4059 string_appendn (declp, (*mangled), scan - (*mangled));
4060 string_need (declp, 1);
4061 *(declp -> p) = '\0';
4063 /* Consume the function name, including the "__" separating the name
4064 from the signature. We are guaranteed that SCAN points to the
4065 separator. */
4067 (*mangled) = scan + 2;
4068 /* We may be looking at an instantiation of a template function:
4069 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4070 following _F marks the start of the function arguments. Handle
4071 the template arguments first. */
4073 if (HP_DEMANGLING && (**mangled == 'X'))
4075 demangle_arm_hp_template (work, mangled, 0, declp);
4076 /* This leaves MANGLED pointing to the 'F' marking func args */
4079 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4082 /* See if we have an ARM style constructor or destructor operator.
4083 If so, then just record it, clear the decl, and return.
4084 We can't build the actual constructor/destructor decl until later,
4085 when we recover the class name from the signature. */
4087 if (strcmp (declp -> b, "__ct") == 0)
4089 work -> constructor += 1;
4090 string_clear (declp);
4091 return;
4093 else if (strcmp (declp -> b, "__dt") == 0)
4095 work -> destructor += 1;
4096 string_clear (declp);
4097 return;
4101 if (declp->p - declp->b >= 3
4102 && declp->b[0] == 'o'
4103 && declp->b[1] == 'p'
4104 && strchr (cplus_markers, declp->b[2]) != NULL)
4106 /* see if it's an assignment expression */
4107 if (declp->p - declp->b >= 10 /* op$assign_ */
4108 && memcmp (declp->b + 3, "assign_", 7) == 0)
4110 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4112 int len = declp->p - declp->b - 10;
4113 if ((int) strlen (optable[i].in) == len
4114 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4116 string_clear (declp);
4117 string_append (declp, "operator");
4118 string_append (declp, optable[i].out);
4119 string_append (declp, "=");
4120 break;
4124 else
4126 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4128 int len = declp->p - declp->b - 3;
4129 if ((int) strlen (optable[i].in) == len
4130 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4132 string_clear (declp);
4133 string_append (declp, "operator");
4134 string_append (declp, optable[i].out);
4135 break;
4140 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4141 && strchr (cplus_markers, declp->b[4]) != NULL)
4143 /* type conversion operator */
4144 tem = declp->b + 5;
4145 if (do_type (work, &tem, &type))
4147 string_clear (declp);
4148 string_append (declp, "operator ");
4149 string_appends (declp, &type);
4150 string_delete (&type);
4153 else if (declp->b[0] == '_' && declp->b[1] == '_'
4154 && declp->b[2] == 'o' && declp->b[3] == 'p')
4156 /* ANSI. */
4157 /* type conversion operator. */
4158 tem = declp->b + 4;
4159 if (do_type (work, &tem, &type))
4161 string_clear (declp);
4162 string_append (declp, "operator ");
4163 string_appends (declp, &type);
4164 string_delete (&type);
4167 else if (declp->b[0] == '_' && declp->b[1] == '_'
4168 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4169 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4171 if (declp->b[4] == '\0')
4173 /* Operator. */
4174 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4176 if (strlen (optable[i].in) == 2
4177 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4179 string_clear (declp);
4180 string_append (declp, "operator");
4181 string_append (declp, optable[i].out);
4182 break;
4186 else
4188 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4190 /* Assignment. */
4191 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4193 if (strlen (optable[i].in) == 3
4194 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4196 string_clear (declp);
4197 string_append (declp, "operator");
4198 string_append (declp, optable[i].out);
4199 break;
4207 /* a mini string-handling package */
4209 static void
4210 string_need (s, n)
4211 string *s;
4212 int n;
4214 int tem;
4216 if (s->b == NULL)
4218 if (n < 32)
4220 n = 32;
4222 s->p = s->b = xmalloc (n);
4223 s->e = s->b + n;
4225 else if (s->e - s->p < n)
4227 tem = s->p - s->b;
4228 n += tem;
4229 n *= 2;
4230 s->b = xrealloc (s->b, n);
4231 s->p = s->b + tem;
4232 s->e = s->b + n;
4236 static void
4237 string_delete (s)
4238 string *s;
4240 if (s->b != NULL)
4242 free (s->b);
4243 s->b = s->e = s->p = NULL;
4247 static void
4248 string_init (s)
4249 string *s;
4251 s->b = s->p = s->e = NULL;
4254 static void
4255 string_clear (s)
4256 string *s;
4258 s->p = s->b;
4261 #if 0
4263 static int
4264 string_empty (s)
4265 string *s;
4267 return (s->b == s->p);
4270 #endif
4272 static void
4273 string_append (p, s)
4274 string *p;
4275 const char *s;
4277 int n;
4278 if (s == NULL || *s == '\0')
4279 return;
4280 n = strlen (s);
4281 string_need (p, n);
4282 memcpy (p->p, s, n);
4283 p->p += n;
4286 static void
4287 string_appends (p, s)
4288 string *p, *s;
4290 int n;
4292 if (s->b != s->p)
4294 n = s->p - s->b;
4295 string_need (p, n);
4296 memcpy (p->p, s->b, n);
4297 p->p += n;
4301 static void
4302 string_appendn (p, s, n)
4303 string *p;
4304 const char *s;
4305 int n;
4307 if (n != 0)
4309 string_need (p, n);
4310 memcpy (p->p, s, n);
4311 p->p += n;
4315 static void
4316 string_prepend (p, s)
4317 string *p;
4318 const char *s;
4320 if (s != NULL && *s != '\0')
4322 string_prependn (p, s, strlen (s));
4326 static void
4327 string_prepends (p, s)
4328 string *p, *s;
4330 if (s->b != s->p)
4332 string_prependn (p, s->b, s->p - s->b);
4336 static void
4337 string_prependn (p, s, n)
4338 string *p;
4339 const char *s;
4340 int n;
4342 char *q;
4344 if (n != 0)
4346 string_need (p, n);
4347 for (q = p->p - 1; q >= p->b; q--)
4349 q[n] = q[0];
4351 memcpy (p->b, s, n);
4352 p->p += n;
4356 /* To generate a standalone demangler program for testing purposes,
4357 just compile and link this file with -DMAIN and libiberty.a. When
4358 run, it demangles each command line arg, or each stdin string, and
4359 prints the result on stdout. */
4361 #ifdef MAIN
4363 #include "getopt.h"
4365 static const char *program_name;
4366 static const char *program_version = VERSION;
4367 static int flags = DMGL_PARAMS | DMGL_ANSI;
4369 static void demangle_it PARAMS ((char *));
4370 static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
4371 static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
4373 static void
4374 demangle_it (mangled_name)
4375 char *mangled_name;
4377 char *result;
4379 result = cplus_demangle (mangled_name, flags);
4380 if (result == NULL)
4382 printf ("%s\n", mangled_name);
4384 else
4386 printf ("%s\n", result);
4387 free (result);
4391 static void
4392 usage (stream, status)
4393 FILE *stream;
4394 int status;
4396 fprintf (stream, "\
4397 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4398 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4399 [--help] [--version] [arg...]\n",
4400 program_name);
4401 exit (status);
4404 #define MBUF_SIZE 32767
4405 char mbuffer[MBUF_SIZE];
4407 /* Defined in the automatically-generated underscore.c. */
4408 extern int prepends_underscore;
4410 int strip_underscore = 0;
4412 static struct option long_options[] = {
4413 {"strip-underscores", no_argument, 0, '_'},
4414 {"format", required_argument, 0, 's'},
4415 {"help", no_argument, 0, 'h'},
4416 {"java", no_argument, 0, 'j'},
4417 {"no-strip-underscores", no_argument, 0, 'n'},
4418 {"version", no_argument, 0, 'v'},
4419 {0, no_argument, 0, 0}
4422 /* More 'friendly' abort that prints the line and file.
4423 config.h can #define abort fancy_abort if you like that sort of thing. */
4425 void
4426 fancy_abort ()
4428 fatal ("Internal gcc abort.");
4432 /* Return the string of non-alnum characters that may occur
4433 as a valid symbol component, in the standard assembler symbol
4434 syntax. */
4436 static const char *
4437 standard_symbol_characters ()
4439 return "_$.";
4443 /* Return the string of non-alnum characters that may occur
4444 as a valid symbol name component in an HP object file.
4446 Note that, since HP's compiler generates object code straight from
4447 C++ source, without going through an assembler, its mangled
4448 identifiers can use all sorts of characters that no assembler would
4449 tolerate, so the alphabet this function creates is a little odd.
4450 Here are some sample mangled identifiers offered by HP:
4452 typeid*__XT24AddressIndExpClassMember_
4453 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4454 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4456 This still seems really weird to me, since nowhere else in this
4457 file is there anything to recognize curly brackets, parens, etc.
4458 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4459 this is right, but I still strongly suspect that there's a
4460 misunderstanding here.
4462 If we decide it's better for c++filt to use HP's assembler syntax
4463 to scrape identifiers out of its input, here's the definition of
4464 the symbol name syntax from the HP assembler manual:
4466 Symbols are composed of uppercase and lowercase letters, decimal
4467 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4468 underscore (_). A symbol can begin with a letter, digit underscore or
4469 dollar sign. If a symbol begins with a digit, it must contain a
4470 non-digit character.
4472 So have fun. */
4473 static const char *
4474 hp_symbol_characters ()
4476 return "_$.<>#,*&[]:(){}";
4480 extern int main PARAMS ((int, char **));
4483 main (argc, argv)
4484 int argc;
4485 char **argv;
4487 char *result;
4488 int c;
4489 const char *valid_symbols;
4491 program_name = argv[0];
4493 strip_underscore = prepends_underscore;
4495 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4497 switch (c)
4499 case '?':
4500 usage (stderr, 1);
4501 break;
4502 case 'h':
4503 usage (stdout, 0);
4504 case 'n':
4505 strip_underscore = 0;
4506 break;
4507 case 'v':
4508 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4509 return (0);
4510 case '_':
4511 strip_underscore = 1;
4512 break;
4513 case 'j':
4514 flags |= DMGL_JAVA;
4515 break;
4516 case 's':
4517 if (strcmp (optarg, "gnu") == 0)
4519 current_demangling_style = gnu_demangling;
4521 else if (strcmp (optarg, "lucid") == 0)
4523 current_demangling_style = lucid_demangling;
4525 else if (strcmp (optarg, "arm") == 0)
4527 current_demangling_style = arm_demangling;
4529 else if (strcmp (optarg, "hp") == 0)
4531 current_demangling_style = hp_demangling;
4533 else if (strcmp (optarg, "edg") == 0)
4535 current_demangling_style = edg_demangling;
4537 else
4539 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4540 program_name, optarg);
4541 return (1);
4543 break;
4547 if (optind < argc)
4549 for ( ; optind < argc; optind++)
4551 demangle_it (argv[optind]);
4554 else
4556 switch (current_demangling_style)
4558 case gnu_demangling:
4559 case lucid_demangling:
4560 case arm_demangling:
4561 case edg_demangling:
4562 valid_symbols = standard_symbol_characters ();
4563 break;
4564 case hp_demangling:
4565 valid_symbols = hp_symbol_characters ();
4566 break;
4567 default:
4568 /* Folks should explicitly indicate the appropriate alphabet for
4569 each demangling. Providing a default would allow the
4570 question to go unconsidered. */
4571 abort ();
4574 for (;;)
4576 int i = 0;
4577 c = getchar ();
4578 /* Try to read a label. */
4579 while (c != EOF && (isalnum (c) || strchr (valid_symbols, c)))
4581 if (i >= MBUF_SIZE-1)
4582 break;
4583 mbuffer[i++] = c;
4584 c = getchar ();
4586 if (i > 0)
4588 int skip_first = 0;
4590 if (mbuffer[0] == '.')
4591 ++skip_first;
4592 if (strip_underscore && mbuffer[skip_first] == '_')
4593 ++skip_first;
4595 if (skip_first > i)
4596 skip_first = i;
4598 mbuffer[i] = 0;
4600 result = cplus_demangle (mbuffer + skip_first, flags);
4601 if (result)
4603 if (mbuffer[0] == '.')
4604 putc ('.', stdout);
4605 fputs (result, stdout);
4606 free (result);
4608 else
4609 fputs (mbuffer, stdout);
4611 fflush (stdout);
4613 if (c == EOF)
4614 break;
4615 putchar (c);
4619 return (0);
4622 static void
4623 fatal (str)
4624 const char *str;
4626 fprintf (stderr, "%s: %s\n", program_name, str);
4627 exit (1);
4631 xmalloc (size)
4632 size_t size;
4634 register PTR value = (PTR) malloc (size);
4635 if (value == 0)
4636 fatal ("virtual memory exhausted");
4637 return value;
4641 xrealloc (ptr, size)
4642 PTR ptr;
4643 size_t size;
4645 register PTR value = (PTR) realloc (ptr, size);
4646 if (value == 0)
4647 fatal ("virtual memory exhausted");
4648 return value;
4650 #endif /* main */