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
29 /* This file lives in both GCC and libiberty. When making changes, please
30 try not to break either. */
37 #include <sys/types.h>
49 #undef CURRENT_DEMANGLING_STYLE
50 #define CURRENT_DEMANGLING_STYLE work->options
52 #include "libiberty.h"
54 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
56 /* A value at least one greater than the maximum number of characters
57 that will be output when using the `%d' format with `printf'. */
58 #define INTBUF_SIZE 32
60 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
62 static const char *mystrstr PARAMS ((const char *, const char *));
68 register const char *p = s1;
69 register int len = strlen (s2);
71 for (; (p = strchr (p, *s2)) != 0; p++)
73 if (strncmp (p, s2, len) == 0)
81 /* In order to allow a single demangler executable to demangle strings
82 using various common values of CPLUS_MARKER, as well as any specific
83 one set at compile time, we maintain a string containing all the
84 commonly used ones, and check to see if the marker we are looking for
85 is in that string. CPLUS_MARKER is usually '$' on systems where the
86 assembler can deal with that. Where the assembler can't, it's usually
87 '.' (but on many systems '.' is used for other things). We put the
88 current defined CPLUS_MARKER first (which defaults to '$'), followed
89 by the next most common value, followed by an explicit '$' in case
90 the value of CPLUS_MARKER is not '$'.
92 We could avoid this if we could just get g++ to tell us what the actual
93 cplus marker character is as part of the debug information, perhaps by
94 ensuring that it is the character that terminates the gcc<n>_compiled
95 marker symbol (FIXME). */
97 #if !defined (CPLUS_MARKER)
98 #define CPLUS_MARKER '$'
101 enum demangling_styles current_demangling_style = gnu_demangling;
103 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
105 static char char_str[2] = { '\000', '\000' };
108 set_cplus_marker_for_demangling (ch)
111 cplus_markers[0] = ch;
114 typedef struct string /* Beware: these aren't required to be */
115 { /* '\0' terminated. */
116 char *b; /* pointer to start of string */
117 char *p; /* pointer after last character */
118 char *e; /* pointer after end of allocated space */
121 /* Stuff that is shared between sub-routines.
122 Using a shared structure allows cplus_demangle to be reentrant. */
138 int static_type; /* A static member function */
139 int temp_start; /* index in demangled to start of template args */
140 int type_quals; /* The type qualifiers. */
141 int dllimported; /* Symbol imported from a PE DLL */
142 char **tmpl_argvec; /* Template function arguments. */
143 int ntmpl_args; /* The number of template function arguments. */
144 int forgetting_types; /* Nonzero if we are not remembering the types
146 string* previous_argument; /* The last function argument demangled. */
147 int nrepeats; /* The number of times to repeat the previous
151 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
152 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
154 static const struct optable
160 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
161 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
162 {"new", " new", 0}, /* old (1.91, and 1.x) */
163 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
164 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
165 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
166 {"as", "=", DMGL_ANSI}, /* ansi */
167 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
168 {"eq", "==", DMGL_ANSI}, /* old, ansi */
169 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
170 {"gt", ">", DMGL_ANSI}, /* old, ansi */
171 {"le", "<=", DMGL_ANSI}, /* old, ansi */
172 {"lt", "<", DMGL_ANSI}, /* old, ansi */
173 {"plus", "+", 0}, /* old */
174 {"pl", "+", DMGL_ANSI}, /* ansi */
175 {"apl", "+=", DMGL_ANSI}, /* ansi */
176 {"minus", "-", 0}, /* old */
177 {"mi", "-", DMGL_ANSI}, /* ansi */
178 {"ami", "-=", DMGL_ANSI}, /* ansi */
179 {"mult", "*", 0}, /* old */
180 {"ml", "*", DMGL_ANSI}, /* ansi */
181 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
182 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
183 {"convert", "+", 0}, /* old (unary +) */
184 {"negate", "-", 0}, /* old (unary -) */
185 {"trunc_mod", "%", 0}, /* old */
186 {"md", "%", DMGL_ANSI}, /* ansi */
187 {"amd", "%=", DMGL_ANSI}, /* ansi */
188 {"trunc_div", "/", 0}, /* old */
189 {"dv", "/", DMGL_ANSI}, /* ansi */
190 {"adv", "/=", DMGL_ANSI}, /* ansi */
191 {"truth_andif", "&&", 0}, /* old */
192 {"aa", "&&", DMGL_ANSI}, /* ansi */
193 {"truth_orif", "||", 0}, /* old */
194 {"oo", "||", DMGL_ANSI}, /* ansi */
195 {"truth_not", "!", 0}, /* old */
196 {"nt", "!", DMGL_ANSI}, /* ansi */
197 {"postincrement","++", 0}, /* old */
198 {"pp", "++", DMGL_ANSI}, /* ansi */
199 {"postdecrement","--", 0}, /* old */
200 {"mm", "--", DMGL_ANSI}, /* ansi */
201 {"bit_ior", "|", 0}, /* old */
202 {"or", "|", DMGL_ANSI}, /* ansi */
203 {"aor", "|=", DMGL_ANSI}, /* ansi */
204 {"bit_xor", "^", 0}, /* old */
205 {"er", "^", DMGL_ANSI}, /* ansi */
206 {"aer", "^=", DMGL_ANSI}, /* ansi */
207 {"bit_and", "&", 0}, /* old */
208 {"ad", "&", DMGL_ANSI}, /* ansi */
209 {"aad", "&=", DMGL_ANSI}, /* ansi */
210 {"bit_not", "~", 0}, /* old */
211 {"co", "~", DMGL_ANSI}, /* ansi */
212 {"call", "()", 0}, /* old */
213 {"cl", "()", DMGL_ANSI}, /* ansi */
214 {"alshift", "<<", 0}, /* old */
215 {"ls", "<<", DMGL_ANSI}, /* ansi */
216 {"als", "<<=", DMGL_ANSI}, /* ansi */
217 {"arshift", ">>", 0}, /* old */
218 {"rs", ">>", DMGL_ANSI}, /* ansi */
219 {"ars", ">>=", DMGL_ANSI}, /* ansi */
220 {"component", "->", 0}, /* old */
221 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
222 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
223 {"indirect", "*", 0}, /* old */
224 {"method_call", "->()", 0}, /* old */
225 {"addr", "&", 0}, /* old (unary &) */
226 {"array", "[]", 0}, /* old */
227 {"vc", "[]", DMGL_ANSI}, /* ansi */
228 {"compound", ", ", 0}, /* old */
229 {"cm", ", ", DMGL_ANSI}, /* ansi */
230 {"cond", "?:", 0}, /* old */
231 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
232 {"max", ">?", 0}, /* old */
233 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
234 {"min", "<?", 0}, /* old */
235 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
236 {"nop", "", 0}, /* old (for operator=) */
237 {"rm", "->*", DMGL_ANSI}, /* ansi */
238 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
241 /* These values are used to indicate the various type varieties.
242 They are all non-zero so that they can be used as `success'
244 typedef enum type_kind_t
255 struct demangler_engine libiberty_demanglers[] =
258 AUTO_DEMANGLING_STYLE_STRING,
260 "Automatic selection based on executable"
264 GNU_DEMANGLING_STYLE_STRING,
266 "GNU (g++) style demangling"
270 LUCID_DEMANGLING_STYLE_STRING,
272 "Lucid (lcc) style demangling"
276 ARM_DEMANGLING_STYLE_STRING,
278 "ARM style demangling"
282 HP_DEMANGLING_STYLE_STRING,
284 "HP (aCC) style demangling"
288 EDG_DEMANGLING_STYLE_STRING,
290 "EDG style demangling"
294 GNU_NEW_ABI_DEMANGLING_STYLE_STRING,
295 gnu_new_abi_demangling,
296 "GNU (g++) new-ABI-style demangling"
300 NULL, unknown_demangling, NULL
304 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
305 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
306 string_prepend(str, " ");}
307 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
308 string_append(str, " ");}
309 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
311 /* The scope separator appropriate for the language being demangled. */
313 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
315 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
316 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
318 /* Prototypes for local functions */
321 mop_up PARAMS ((struct work_stuff *, string *, int));
324 squangle_mop_up PARAMS ((struct work_stuff *));
328 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
332 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
335 demangle_template_template_parm PARAMS ((struct work_stuff *work,
336 const char **, string *));
339 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
340 string *, int, int));
343 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
347 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
350 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
354 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
357 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
360 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
363 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
366 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
369 arm_special PARAMS ((const char **, string *));
372 string_need PARAMS ((string *, int));
375 string_delete PARAMS ((string *));
378 string_init PARAMS ((string *));
381 string_clear PARAMS ((string *));
385 string_empty PARAMS ((string *));
389 string_append PARAMS ((string *, const char *));
392 string_appends PARAMS ((string *, string *));
395 string_appendn PARAMS ((string *, const char *, int));
398 string_prepend PARAMS ((string *, const char *));
401 string_prependn PARAMS ((string *, const char *, int));
404 string_append_template_idx PARAMS ((string *, int));
407 get_count PARAMS ((const char **, int *));
410 consume_count PARAMS ((const char **));
413 consume_count_with_underscores PARAMS ((const char**));
416 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
419 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
422 do_type PARAMS ((struct work_stuff *, const char **, string *));
425 do_arg PARAMS ((struct work_stuff *, const char **, string *));
428 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
432 remember_type PARAMS ((struct work_stuff *, const char *, int));
435 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
438 register_Btype PARAMS ((struct work_stuff *));
441 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
444 forget_types PARAMS ((struct work_stuff *));
447 forget_B_and_K_types PARAMS ((struct work_stuff *));
450 string_prepends PARAMS ((string *, string *));
453 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
454 string*, type_kind_t));
457 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
460 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
463 snarf_numeric_literal PARAMS ((const char **, string *));
465 /* There is a TYPE_QUAL value for each type qualifier. They can be
466 combined by bitwise-or to form the complete set of qualifiers for a
469 #define TYPE_UNQUALIFIED 0x0
470 #define TYPE_QUAL_CONST 0x1
471 #define TYPE_QUAL_VOLATILE 0x2
472 #define TYPE_QUAL_RESTRICT 0x4
475 code_for_qualifier PARAMS ((int));
478 qualifier_string PARAMS ((int));
481 demangle_qualifier PARAMS ((int));
484 demangle_expression PARAMS ((struct work_stuff *, const char **, string *,
488 demangle_integral_value PARAMS ((struct work_stuff *, const char **,
492 demangle_real_value PARAMS ((struct work_stuff *, const char **, string *));
495 demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
499 recursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
502 /* Translate count to integer, consuming tokens in the process.
503 Conversion terminates on the first non-digit character.
505 Trying to consume something that isn't a count results in no
506 consumption of input and a return of -1.
508 Overflow consumes the rest of the digits, and returns -1. */
516 if (! isdigit ((unsigned char)**type))
519 while (isdigit ((unsigned char)**type))
523 /* Check for overflow.
524 We assume that count is represented using two's-complement;
525 no power of two is divisible by ten, so if an overflow occurs
526 when multiplying by ten, the result will not be a multiple of
528 if ((count % 10) != 0)
530 while (isdigit ((unsigned char) **type))
535 count += **type - '0';
543 /* Like consume_count, but for counts that are preceded and followed
544 by '_' if they are greater than 10. Also, -1 is returned for
545 failure, since 0 can be a valid value. */
548 consume_count_with_underscores (mangled)
549 const char **mangled;
553 if (**mangled == '_')
556 if (!isdigit ((unsigned char)**mangled))
559 idx = consume_count (mangled);
560 if (**mangled != '_')
561 /* The trailing underscore was missing. */
568 if (**mangled < '0' || **mangled > '9')
571 idx = **mangled - '0';
578 /* C is the code for a type-qualifier. Return the TYPE_QUAL
579 corresponding to this qualifier. */
582 code_for_qualifier (c)
588 return TYPE_QUAL_CONST;
591 return TYPE_QUAL_VOLATILE;
594 return TYPE_QUAL_RESTRICT;
600 /* C was an invalid qualifier. */
604 /* Return the string corresponding to the qualifiers given by
608 qualifier_string (type_quals)
613 case TYPE_UNQUALIFIED:
616 case TYPE_QUAL_CONST:
619 case TYPE_QUAL_VOLATILE:
622 case TYPE_QUAL_RESTRICT:
625 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
626 return "const volatile";
628 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
629 return "const __restrict";
631 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
632 return "volatile __restrict";
634 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
635 return "const volatile __restrict";
641 /* TYPE_QUALS was an invalid qualifier set. */
645 /* C is the code for a type-qualifier. Return the string
646 corresponding to this qualifier. This function should only be
647 called with a valid qualifier code. */
650 demangle_qualifier (c)
653 return qualifier_string (code_for_qualifier (c));
657 cplus_demangle_opname (opname, result, options)
664 struct work_stuff work[1];
667 len = strlen(opname);
670 memset ((char *) work, 0, sizeof (work));
671 work->options = options;
673 if (opname[0] == '_' && opname[1] == '_'
674 && opname[2] == 'o' && opname[3] == 'p')
677 /* type conversion operator. */
679 if (do_type (work, &tem, &type))
681 strcat (result, "operator ");
682 strncat (result, type.b, type.p - type.b);
683 string_delete (&type);
687 else if (opname[0] == '_' && opname[1] == '_'
688 && islower((unsigned char)opname[2])
689 && islower((unsigned char)opname[3]))
691 if (opname[4] == '\0')
695 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
697 if (strlen (optable[i].in) == 2
698 && memcmp (optable[i].in, opname + 2, 2) == 0)
700 strcat (result, "operator");
701 strcat (result, optable[i].out);
709 if (opname[2] == 'a' && opname[5] == '\0')
713 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
715 if (strlen (optable[i].in) == 3
716 && memcmp (optable[i].in, opname + 2, 3) == 0)
718 strcat (result, "operator");
719 strcat (result, optable[i].out);
730 && strchr (cplus_markers, opname[2]) != NULL)
732 /* see if it's an assignment expression */
733 if (len >= 10 /* op$assign_ */
734 && memcmp (opname + 3, "assign_", 7) == 0)
737 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
740 if ((int) strlen (optable[i].in) == len1
741 && memcmp (optable[i].in, opname + 10, len1) == 0)
743 strcat (result, "operator");
744 strcat (result, optable[i].out);
745 strcat (result, "=");
754 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
757 if ((int) strlen (optable[i].in) == len1
758 && memcmp (optable[i].in, opname + 3, len1) == 0)
760 strcat (result, "operator");
761 strcat (result, optable[i].out);
768 else if (len >= 5 && memcmp (opname, "type", 4) == 0
769 && strchr (cplus_markers, opname[4]) != NULL)
771 /* type conversion operator */
773 if (do_type (work, &tem, &type))
775 strcat (result, "operator ");
776 strncat (result, type.b, type.p - type.b);
777 string_delete (&type);
781 squangle_mop_up (work);
786 /* Takes operator name as e.g. "++" and returns mangled
787 operator name (e.g. "postincrement_expr"), or NULL if not found.
789 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
790 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
793 cplus_mangle_opname (opname, options)
800 len = strlen (opname);
801 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
803 if ((int) strlen (optable[i].out) == len
804 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
805 && memcmp (optable[i].out, opname, len) == 0)
806 return optable[i].in;
811 /* Add a routine to set the demangling style to be sure it is valid and
812 allow for any demangler initialization that maybe necessary. */
814 enum demangling_styles
815 cplus_demangle_set_style (style)
816 enum demangling_styles style;
818 struct demangler_engine *demangler = libiberty_demanglers;
820 for (; demangler->demangling_style != unknown_demangling; ++demangler)
821 if (style == demangler->demangling_style)
823 current_demangling_style = style;
824 return current_demangling_style;
827 return unknown_demangling;
830 /* Do string name to style translation */
832 enum demangling_styles
833 cplus_demangle_name_to_style (name)
836 struct demangler_engine *demangler = libiberty_demanglers;
838 for (; demangler->demangling_style != unknown_demangling; ++demangler)
839 if (strcmp (name, demangler->demangling_style_name) == 0)
840 return demangler->demangling_style;
842 return unknown_demangling;
845 /* char *cplus_demangle (const char *mangled, int options)
847 If MANGLED is a mangled function name produced by GNU C++, then
848 a pointer to a malloced string giving a C++ representation
849 of the name will be returned; otherwise NULL will be returned.
850 It is the caller's responsibility to free the string which
853 The OPTIONS arg may contain one or more of the following bits:
855 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
857 DMGL_PARAMS Function parameters are included.
861 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
862 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
863 cplus_demangle ("foo__1Ai", 0) => "A::foo"
865 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
866 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
867 cplus_demangle ("foo__1Afe", 0) => "A::foo"
869 Note that any leading underscores, or other such characters prepended by
870 the compilation system, are presumed to have already been stripped from
874 cplus_demangle (mangled, options)
879 struct work_stuff work[1];
880 memset ((char *) work, 0, sizeof (work));
881 work -> options = options;
882 if ((work -> options & DMGL_STYLE_MASK) == 0)
883 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
885 /* The new-ABI demangling is implemented elsewhere. */
886 if (GNU_NEW_ABI_DEMANGLING)
887 return cplus_demangle_new_abi (mangled);
889 ret = internal_cplus_demangle (work, mangled);
890 squangle_mop_up (work);
895 /* This function performs most of what cplus_demangle use to do, but
896 to be able to demangle a name with a B, K or n code, we need to
897 have a longer term memory of what types have been seen. The original
898 now intializes and cleans up the squangle code info, while internal
899 calls go directly to this routine to avoid resetting that info. */
902 internal_cplus_demangle (work, mangled)
903 struct work_stuff *work;
909 char *demangled = NULL;
911 s1 = work->constructor;
912 s2 = work->destructor;
913 s3 = work->static_type;
914 s4 = work->type_quals;
915 work->constructor = work->destructor = 0;
916 work->type_quals = TYPE_UNQUALIFIED;
917 work->dllimported = 0;
919 if ((mangled != NULL) && (*mangled != '\0'))
923 /* First check to see if gnu style demangling is active and if the
924 string to be demangled contains a CPLUS_MARKER. If so, attempt to
925 recognize one of the gnu special forms rather than looking for a
926 standard prefix. In particular, don't worry about whether there
927 is a "__" string in the mangled string. Consider "_$_5__foo" for
930 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
932 success = gnu_special (work, &mangled, &decl);
936 success = demangle_prefix (work, &mangled, &decl);
938 if (success && (*mangled != '\0'))
940 success = demangle_signature (work, &mangled, &decl);
942 if (work->constructor == 2)
944 string_prepend (&decl, "global constructors keyed to ");
945 work->constructor = 0;
947 else if (work->destructor == 2)
949 string_prepend (&decl, "global destructors keyed to ");
950 work->destructor = 0;
952 else if (work->dllimported == 1)
954 string_prepend (&decl, "import stub for ");
955 work->dllimported = 0;
957 demangled = mop_up (work, &decl, success);
959 work->constructor = s1;
960 work->destructor = s2;
961 work->static_type = s3;
962 work->type_quals = s4;
967 /* Clear out and squangling related storage */
969 squangle_mop_up (work)
970 struct work_stuff *work;
972 /* clean up the B and K type mangling types. */
973 forget_B_and_K_types (work);
974 if (work -> btypevec != NULL)
976 free ((char *) work -> btypevec);
978 if (work -> ktypevec != NULL)
980 free ((char *) work -> ktypevec);
984 /* Clear out any mangled storage */
987 mop_up (work, declp, success)
988 struct work_stuff *work;
992 char *demangled = NULL;
994 /* Discard the remembered types, if any. */
997 if (work -> typevec != NULL)
999 free ((char *) work -> typevec);
1000 work -> typevec = NULL;
1001 work -> typevec_size = 0;
1003 if (work->tmpl_argvec)
1007 for (i = 0; i < work->ntmpl_args; i++)
1008 if (work->tmpl_argvec[i])
1009 free ((char*) work->tmpl_argvec[i]);
1011 free ((char*) work->tmpl_argvec);
1012 work->tmpl_argvec = NULL;
1014 if (work->previous_argument)
1016 string_delete (work->previous_argument);
1017 free ((char*) work->previous_argument);
1018 work->previous_argument = NULL;
1021 /* If demangling was successful, ensure that the demangled string is null
1022 terminated and return it. Otherwise, free the demangling decl. */
1026 string_delete (declp);
1030 string_appendn (declp, "", 1);
1031 demangled = declp -> b;
1040 demangle_signature -- demangle the signature part of a mangled name
1045 demangle_signature (struct work_stuff *work, const char **mangled,
1050 Consume and demangle the signature portion of the mangled name.
1052 DECLP is the string where demangled output is being built. At
1053 entry it contains the demangled root name from the mangled name
1054 prefix. I.E. either a demangled operator name or the root function
1055 name. In some special cases, it may contain nothing.
1057 *MANGLED points to the current unconsumed location in the mangled
1058 name. As tokens are consumed and demangling is performed, the
1059 pointer is updated to continuously point at the next token to
1062 Demangling GNU style mangled names is nasty because there is no
1063 explicit token that marks the start of the outermost function
1067 demangle_signature (work, mangled, declp)
1068 struct work_stuff *work;
1069 const char **mangled;
1074 int expect_func = 0;
1075 int expect_return_type = 0;
1076 const char *oldmangled = NULL;
1080 while (success && (**mangled != '\0'))
1085 oldmangled = *mangled;
1086 success = demangle_qualified (work, mangled, declp, 1, 0);
1088 remember_type (work, oldmangled, *mangled - oldmangled);
1089 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1095 oldmangled = *mangled;
1096 success = demangle_qualified (work, mangled, declp, 1, 0);
1097 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1105 /* Static member function */
1106 if (oldmangled == NULL)
1108 oldmangled = *mangled;
1111 work -> static_type = 1;
1117 work->type_quals |= code_for_qualifier (**mangled);
1119 /* a qualified member function */
1120 if (oldmangled == NULL)
1121 oldmangled = *mangled;
1126 /* Local class name follows after "Lnnn_" */
1129 while (**mangled && (**mangled != '_'))
1140 case '0': case '1': case '2': case '3': case '4':
1141 case '5': case '6': case '7': case '8': case '9':
1142 if (oldmangled == NULL)
1144 oldmangled = *mangled;
1146 work->temp_start = -1; /* uppermost call to demangle_class */
1147 success = demangle_class (work, mangled, declp);
1150 remember_type (work, oldmangled, *mangled - oldmangled);
1152 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1154 /* EDG and others will have the "F", so we let the loop cycle
1155 if we are looking at one. */
1156 if (**mangled != 'F')
1165 success = do_type (work, mangled, &s);
1168 string_append (&s, SCOPE_STRING (work));
1169 string_prepends (declp, &s);
1178 /* ARM/HP style demangling includes a specific 'F' character after
1179 the class name. For GNU style, it is just implied. So we can
1180 safely just consume any 'F' at this point and be compatible
1181 with either style. */
1187 /* For lucid/ARM/HP style we have to forget any types we might
1188 have remembered up to this point, since they were not argument
1189 types. GNU style considers all types seen as available for
1190 back references. See comment in demangle_args() */
1192 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1194 forget_types (work);
1196 success = demangle_args (work, mangled, declp);
1197 /* After picking off the function args, we expect to either
1198 find the function return type (preceded by an '_') or the
1199 end of the string. */
1200 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1203 /* At this level, we do not care about the return type. */
1204 success = do_type (work, mangled, &tname);
1205 string_delete (&tname);
1212 string_init(&trawname);
1213 string_init(&tname);
1214 if (oldmangled == NULL)
1216 oldmangled = *mangled;
1218 success = demangle_template (work, mangled, &tname,
1222 remember_type (work, oldmangled, *mangled - oldmangled);
1224 string_append (&tname, SCOPE_STRING (work));
1226 string_prepends(declp, &tname);
1227 if (work -> destructor & 1)
1229 string_prepend (&trawname, "~");
1230 string_appends (declp, &trawname);
1231 work->destructor -= 1;
1233 if ((work->constructor & 1) || (work->destructor & 1))
1235 string_appends (declp, &trawname);
1236 work->constructor -= 1;
1238 string_delete(&trawname);
1239 string_delete(&tname);
1245 if (GNU_DEMANGLING && expect_return_type)
1247 /* Read the return type. */
1249 string_init (&return_type);
1252 success = do_type (work, mangled, &return_type);
1253 APPEND_BLANK (&return_type);
1255 string_prepends (declp, &return_type);
1256 string_delete (&return_type);
1260 /* At the outermost level, we cannot have a return type specified,
1261 so if we run into another '_' at this point we are dealing with
1262 a mangled name that is either bogus, or has been mangled by
1263 some algorithm we don't know how to deal with. So just
1264 reject the entire demangling. */
1265 /* However, "_nnn" is an expected suffix for alternate entry point
1266 numbered nnn for a function, with HP aCC, so skip over that
1267 without reporting failure. pai/1997-09-04 */
1271 while (**mangled && isdigit ((unsigned char)**mangled))
1281 /* A G++ template function. Read the template arguments. */
1282 success = demangle_template (work, mangled, declp, 0, 0,
1284 if (!(work->constructor & 1))
1285 expect_return_type = 1;
1294 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1296 /* Assume we have stumbled onto the first outermost function
1297 argument token, and start processing args. */
1299 success = demangle_args (work, mangled, declp);
1303 /* Non-GNU demanglers use a specific token to mark the start
1304 of the outermost function argument tokens. Typically 'F',
1305 for ARM/HP-demangling, for example. So if we find something
1306 we are not prepared for, it must be an error. */
1312 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1315 if (success && expect_func)
1318 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1320 forget_types (work);
1322 success = demangle_args (work, mangled, declp);
1323 /* Since template include the mangling of their return types,
1324 we must set expect_func to 0 so that we don't try do
1325 demangle more arguments the next time we get here. */
1330 if (success && !func_done)
1332 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1334 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1335 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1336 first case, and need to ensure that the '(void)' gets added to
1337 the current declp. Note that with ARM/HP, the first case
1338 represents the name of a static data member 'foo::bar',
1339 which is in the current declp, so we leave it alone. */
1340 success = demangle_args (work, mangled, declp);
1343 if (success && PRINT_ARG_TYPES)
1345 if (work->static_type)
1346 string_append (declp, " static");
1347 if (work->type_quals != TYPE_UNQUALIFIED)
1349 APPEND_BLANK (declp);
1350 string_append (declp, qualifier_string (work->type_quals));
1360 demangle_method_args (work, mangled, declp)
1361 struct work_stuff *work;
1362 const char **mangled;
1367 if (work -> static_type)
1369 string_append (declp, *mangled + 1);
1370 *mangled += strlen (*mangled);
1375 success = demangle_args (work, mangled, declp);
1383 demangle_template_template_parm (work, mangled, tname)
1384 struct work_stuff *work;
1385 const char **mangled;
1394 string_append (tname, "template <");
1395 /* get size of template parameter list */
1396 if (get_count (mangled, &r))
1398 for (i = 0; i < r; i++)
1402 string_append (tname, ", ");
1405 /* Z for type parameters */
1406 if (**mangled == 'Z')
1409 string_append (tname, "class");
1411 /* z for template parameters */
1412 else if (**mangled == 'z')
1416 demangle_template_template_parm (work, mangled, tname);
1424 /* temp is initialized in do_type */
1425 success = do_type (work, mangled, &temp);
1428 string_appends (tname, &temp);
1430 string_delete(&temp);
1440 if (tname->p[-1] == '>')
1441 string_append (tname, " ");
1442 string_append (tname, "> class");
1447 demangle_expression (work, mangled, s, tk)
1448 struct work_stuff *work;
1449 const char** mangled;
1453 int need_operator = 0;
1457 string_appendn (s, "(", 1);
1459 while (success && **mangled != 'W' && **mangled != '\0')
1468 len = strlen (*mangled);
1471 i < sizeof (optable) / sizeof (optable [0]);
1474 size_t l = strlen (optable[i].in);
1477 && memcmp (optable[i].in, *mangled, l) == 0)
1479 string_appendn (s, " ", 1);
1480 string_append (s, optable[i].out);
1481 string_appendn (s, " ", 1);
1494 success = demangle_template_value_parm (work, mangled, s, tk);
1497 if (**mangled != 'W')
1501 string_appendn (s, ")", 1);
1509 demangle_integral_value (work, mangled, s)
1510 struct work_stuff *work;
1511 const char** mangled;
1516 if (**mangled == 'E')
1517 success = demangle_expression (work, mangled, s, tk_integral);
1518 else if (**mangled == 'Q' || **mangled == 'K')
1519 success = demangle_qualified (work, mangled, s, 0, 1);
1526 /* Negative numbers are indicated with a leading `m'. */
1527 if (**mangled == 'm')
1529 string_appendn (s, "-", 1);
1533 /* Read the rest of the number. */
1534 value = consume_count_with_underscores (mangled);
1537 char buf[INTBUF_SIZE];
1538 sprintf (buf, "%d", value);
1539 string_append (s, buf);
1541 /* If the next character is an underscore, skip it. */
1542 if (**mangled == '_')
1553 /* Demangle the real value in MANGLED. */
1556 demangle_real_value (work, mangled, s)
1557 struct work_stuff *work;
1558 const char **mangled;
1561 if (**mangled == 'E')
1562 return demangle_expression (work, mangled, s, tk_real);
1564 if (**mangled == 'm')
1566 string_appendn (s, "-", 1);
1569 while (isdigit ((unsigned char)**mangled))
1571 string_appendn (s, *mangled, 1);
1574 if (**mangled == '.') /* fraction */
1576 string_appendn (s, ".", 1);
1578 while (isdigit ((unsigned char)**mangled))
1580 string_appendn (s, *mangled, 1);
1584 if (**mangled == 'e') /* exponent */
1586 string_appendn (s, "e", 1);
1588 while (isdigit ((unsigned char)**mangled))
1590 string_appendn (s, *mangled, 1);
1599 demangle_template_value_parm (work, mangled, s, tk)
1600 struct work_stuff *work;
1601 const char **mangled;
1607 if (**mangled == 'Y')
1609 /* The next argument is a template parameter. */
1613 idx = consume_count_with_underscores (mangled);
1615 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1616 || consume_count_with_underscores (mangled) == -1)
1618 if (work->tmpl_argvec)
1619 string_append (s, work->tmpl_argvec[idx]);
1621 string_append_template_idx (s, idx);
1623 else if (tk == tk_integral)
1624 success = demangle_integral_value (work, mangled, s);
1625 else if (tk == tk_char)
1629 if (**mangled == 'm')
1631 string_appendn (s, "-", 1);
1634 string_appendn (s, "'", 1);
1635 val = consume_count(mangled);
1642 string_appendn (s, &tmp[0], 1);
1643 string_appendn (s, "'", 1);
1646 else if (tk == tk_bool)
1648 int val = consume_count (mangled);
1650 string_appendn (s, "false", 5);
1652 string_appendn (s, "true", 4);
1656 else if (tk == tk_real)
1657 success = demangle_real_value (work, mangled, s);
1658 else if (tk == tk_pointer || tk == tk_reference)
1660 if (**mangled == 'Q')
1661 success = demangle_qualified (work, mangled, s,
1666 int symbol_len = consume_count (mangled);
1667 if (symbol_len == -1)
1669 if (symbol_len == 0)
1670 string_appendn (s, "0", 1);
1673 char *p = xmalloc (symbol_len + 1), *q;
1674 strncpy (p, *mangled, symbol_len);
1675 p [symbol_len] = '\0';
1676 /* We use cplus_demangle here, rather than
1677 internal_cplus_demangle, because the name of the entity
1678 mangled here does not make use of any of the squangling
1679 or type-code information we have built up thus far; it is
1680 mangled independently. */
1681 q = cplus_demangle (p, work->options);
1682 if (tk == tk_pointer)
1683 string_appendn (s, "&", 1);
1684 /* FIXME: Pointer-to-member constants should get a
1685 qualifying class name here. */
1688 string_append (s, q);
1692 string_append (s, p);
1695 *mangled += symbol_len;
1702 /* Demangle the template name in MANGLED. The full name of the
1703 template (e.g., S<int>) is placed in TNAME. The name without the
1704 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1705 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1706 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1707 the tmeplate is remembered in the list of back-referenceable
1711 demangle_template (work, mangled, tname, trawname, is_type, remember)
1712 struct work_stuff *work;
1713 const char **mangled;
1724 int is_java_array = 0;
1732 bindex = register_Btype (work);
1734 /* get template name */
1735 if (**mangled == 'z')
1741 idx = consume_count_with_underscores (mangled);
1743 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1744 || consume_count_with_underscores (mangled) == -1)
1747 if (work->tmpl_argvec)
1749 string_append (tname, work->tmpl_argvec[idx]);
1751 string_append (trawname, work->tmpl_argvec[idx]);
1755 string_append_template_idx (tname, idx);
1757 string_append_template_idx (trawname, idx);
1762 if ((r = consume_count (mangled)) <= 0
1763 || (int) strlen (*mangled) < r)
1767 is_java_array = (work -> options & DMGL_JAVA)
1768 && strncmp (*mangled, "JArray1Z", 8) == 0;
1769 if (! is_java_array)
1771 string_appendn (tname, *mangled, r);
1774 string_appendn (trawname, *mangled, r);
1779 string_append (tname, "<");
1780 /* get size of template parameter list */
1781 if (!get_count (mangled, &r))
1787 /* Create an array for saving the template argument values. */
1788 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1789 work->ntmpl_args = r;
1790 for (i = 0; i < r; i++)
1791 work->tmpl_argvec[i] = 0;
1793 for (i = 0; i < r; i++)
1797 string_append (tname, ", ");
1799 /* Z for type parameters */
1800 if (**mangled == 'Z')
1803 /* temp is initialized in do_type */
1804 success = do_type (work, mangled, &temp);
1807 string_appends (tname, &temp);
1811 /* Save the template argument. */
1812 int len = temp.p - temp.b;
1813 work->tmpl_argvec[i] = xmalloc (len + 1);
1814 memcpy (work->tmpl_argvec[i], temp.b, len);
1815 work->tmpl_argvec[i][len] = '\0';
1818 string_delete(&temp);
1824 /* z for template parameters */
1825 else if (**mangled == 'z')
1829 success = demangle_template_template_parm (work, mangled, tname);
1832 && (r2 = consume_count (mangled)) > 0
1833 && (int) strlen (*mangled) >= r2)
1835 string_append (tname, " ");
1836 string_appendn (tname, *mangled, r2);
1839 /* Save the template argument. */
1841 work->tmpl_argvec[i] = xmalloc (len + 1);
1842 memcpy (work->tmpl_argvec[i], *mangled, len);
1843 work->tmpl_argvec[i][len] = '\0';
1857 /* otherwise, value parameter */
1859 /* temp is initialized in do_type */
1860 success = do_type (work, mangled, &temp);
1861 string_delete(&temp);
1873 success = demangle_template_value_parm (work, mangled, s,
1874 (type_kind_t) success);
1886 int len = s->p - s->b;
1887 work->tmpl_argvec[i] = xmalloc (len + 1);
1888 memcpy (work->tmpl_argvec[i], s->b, len);
1889 work->tmpl_argvec[i][len] = '\0';
1891 string_appends (tname, s);
1899 string_append (tname, "[]");
1903 if (tname->p[-1] == '>')
1904 string_append (tname, " ");
1905 string_append (tname, ">");
1908 if (is_type && remember)
1909 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1912 if (work -> static_type)
1914 string_append (declp, *mangled + 1);
1915 *mangled += strlen (*mangled);
1920 success = demangle_args (work, mangled, declp);
1928 arm_pt (work, mangled, n, anchor, args)
1929 struct work_stuff *work;
1930 const char *mangled;
1932 const char **anchor, **args;
1934 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1935 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1936 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1939 *args = *anchor + 6;
1940 len = consume_count (args);
1943 if (*args + len == mangled + n && **args == '_')
1949 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1951 if ((*anchor = mystrstr (mangled, "__tm__"))
1952 || (*anchor = mystrstr (mangled, "__ps__"))
1953 || (*anchor = mystrstr (mangled, "__pt__")))
1956 *args = *anchor + 6;
1957 len = consume_count (args);
1960 if (*args + len == mangled + n && **args == '_')
1966 else if ((*anchor = mystrstr (mangled, "__S")))
1969 *args = *anchor + 3;
1970 len = consume_count (args);
1973 if (*args + len == mangled + n && **args == '_')
1985 demangle_arm_hp_template (work, mangled, n, declp)
1986 struct work_stuff *work;
1987 const char **mangled;
1993 const char *e = *mangled + n;
1996 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1998 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
2000 char *start_spec_args = NULL;
2002 /* First check for and omit template specialization pseudo-arguments,
2003 such as in "Spec<#1,#1.*>" */
2004 start_spec_args = strchr (*mangled, '<');
2005 if (start_spec_args && (start_spec_args - *mangled < n))
2006 string_appendn (declp, *mangled, start_spec_args - *mangled);
2008 string_appendn (declp, *mangled, n);
2009 (*mangled) += n + 1;
2011 if (work->temp_start == -1) /* non-recursive call */
2012 work->temp_start = declp->p - declp->b;
2013 string_append (declp, "<");
2016 string_clear (&arg);
2020 /* 'T' signals a type parameter */
2022 if (!do_type (work, mangled, &arg))
2023 goto hpacc_template_args_done;
2028 /* 'U' or 'S' signals an integral value */
2029 if (!do_hpacc_template_const_value (work, mangled, &arg))
2030 goto hpacc_template_args_done;
2034 /* 'A' signals a named constant expression (literal) */
2035 if (!do_hpacc_template_literal (work, mangled, &arg))
2036 goto hpacc_template_args_done;
2040 /* Today, 1997-09-03, we have only the above types
2041 of template parameters */
2042 /* FIXME: maybe this should fail and return null */
2043 goto hpacc_template_args_done;
2045 string_appends (declp, &arg);
2046 /* Check if we're at the end of template args.
2047 0 if at end of static member of template class,
2048 _ if done with template args for a function */
2049 if ((**mangled == '\000') || (**mangled == '_'))
2052 string_append (declp, ",");
2054 hpacc_template_args_done:
2055 string_append (declp, ">");
2056 string_delete (&arg);
2057 if (**mangled == '_')
2061 /* ARM template? (Also handles HP cfront extensions) */
2062 else if (arm_pt (work, *mangled, n, &p, &args))
2067 string_appendn (declp, *mangled, p - *mangled);
2068 if (work->temp_start == -1) /* non-recursive call */
2069 work->temp_start = declp->p - declp->b;
2070 string_append (declp, "<");
2071 /* should do error checking here */
2073 string_clear (&arg);
2075 /* Check for type or literal here */
2078 /* HP cfront extensions to ARM for template args */
2079 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2080 /* FIXME: We handle only numeric literals for HP cfront */
2082 /* A typed constant value follows */
2084 if (!do_type (work, &args, &type_str))
2085 goto cfront_template_args_done;
2086 string_append (&arg, "(");
2087 string_appends (&arg, &type_str);
2088 string_append (&arg, ")");
2090 goto cfront_template_args_done;
2092 /* Now snarf a literal value following 'L' */
2093 if (!snarf_numeric_literal (&args, &arg))
2094 goto cfront_template_args_done;
2098 /* Snarf a literal following 'L' */
2100 if (!snarf_numeric_literal (&args, &arg))
2101 goto cfront_template_args_done;
2104 /* Not handling other HP cfront stuff */
2105 if (!do_type (work, &args, &arg))
2106 goto cfront_template_args_done;
2108 string_appends (declp, &arg);
2109 string_append (declp, ",");
2111 cfront_template_args_done:
2112 string_delete (&arg);
2114 --declp->p; /* remove extra comma */
2115 string_append (declp, ">");
2117 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2118 && (*mangled)[9] == 'N'
2119 && (*mangled)[8] == (*mangled)[10]
2120 && strchr (cplus_markers, (*mangled)[8]))
2122 /* A member of the anonymous namespace. */
2123 string_append (declp, "{anonymous}");
2127 if (work->temp_start == -1) /* non-recursive call only */
2128 work->temp_start = 0; /* disable in recursive calls */
2129 string_appendn (declp, *mangled, n);
2134 /* Extract a class name, possibly a template with arguments, from the
2135 mangled string; qualifiers, local class indicators, etc. have
2136 already been dealt with */
2139 demangle_class_name (work, mangled, declp)
2140 struct work_stuff *work;
2141 const char **mangled;
2147 n = consume_count (mangled);
2150 if ((int) strlen (*mangled) >= n)
2152 demangle_arm_hp_template (work, mangled, n, declp);
2163 demangle_class -- demangle a mangled class sequence
2168 demangle_class (struct work_stuff *work, const char **mangled,
2173 DECLP points to the buffer into which demangling is being done.
2175 *MANGLED points to the current token to be demangled. On input,
2176 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2177 On exit, it points to the next token after the mangled class on
2178 success, or the first unconsumed token on failure.
2180 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2181 we are demangling a constructor or destructor. In this case
2182 we prepend "class::class" or "class::~class" to DECLP.
2184 Otherwise, we prepend "class::" to the current DECLP.
2186 Reset the constructor/destructor flags once they have been
2187 "consumed". This allows demangle_class to be called later during
2188 the same demangling, to do normal class demangling.
2190 Returns 1 if demangling is successful, 0 otherwise.
2195 demangle_class (work, mangled, declp)
2196 struct work_stuff *work;
2197 const char **mangled;
2203 char *save_class_name_end = 0;
2205 string_init (&class_name);
2206 btype = register_Btype (work);
2207 if (demangle_class_name (work, mangled, &class_name))
2209 save_class_name_end = class_name.p;
2210 if ((work->constructor & 1) || (work->destructor & 1))
2212 /* adjust so we don't include template args */
2213 if (work->temp_start && (work->temp_start != -1))
2215 class_name.p = class_name.b + work->temp_start;
2217 string_prepends (declp, &class_name);
2218 if (work -> destructor & 1)
2220 string_prepend (declp, "~");
2221 work -> destructor -= 1;
2225 work -> constructor -= 1;
2228 class_name.p = save_class_name_end;
2229 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2230 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2231 string_prepend (declp, SCOPE_STRING (work));
2232 string_prepends (declp, &class_name);
2235 string_delete (&class_name);
2243 demangle_prefix -- consume the mangled name prefix and find signature
2248 demangle_prefix (struct work_stuff *work, const char **mangled,
2253 Consume and demangle the prefix of the mangled name.
2255 DECLP points to the string buffer into which demangled output is
2256 placed. On entry, the buffer is empty. On exit it contains
2257 the root function name, the demangled operator name, or in some
2258 special cases either nothing or the completely demangled result.
2260 MANGLED points to the current pointer into the mangled name. As each
2261 token of the mangled name is consumed, it is updated. Upon entry
2262 the current mangled name pointer points to the first character of
2263 the mangled name. Upon exit, it should point to the first character
2264 of the signature if demangling was successful, or to the first
2265 unconsumed character if demangling of the prefix was unsuccessful.
2267 Returns 1 on success, 0 otherwise.
2271 demangle_prefix (work, mangled, declp)
2272 struct work_stuff *work;
2273 const char **mangled;
2280 if (strlen(*mangled) > 6
2281 && (strncmp(*mangled, "_imp__", 6) == 0
2282 || strncmp(*mangled, "__imp_", 6) == 0))
2284 /* it's a symbol imported from a PE dynamic library. Check for both
2285 new style prefix _imp__ and legacy __imp_ used by older versions
2288 work->dllimported = 1;
2290 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2292 char *marker = strchr (cplus_markers, (*mangled)[8]);
2293 if (marker != NULL && *marker == (*mangled)[10])
2295 if ((*mangled)[9] == 'D')
2297 /* it's a GNU global destructor to be executed at program exit */
2299 work->destructor = 2;
2300 if (gnu_special (work, mangled, declp))
2303 else if ((*mangled)[9] == 'I')
2305 /* it's a GNU global constructor to be executed at program init */
2307 work->constructor = 2;
2308 if (gnu_special (work, mangled, declp))
2313 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2315 /* it's a ARM global destructor to be executed at program exit */
2317 work->destructor = 2;
2319 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2321 /* it's a ARM global constructor to be executed at program initial */
2323 work->constructor = 2;
2326 /* This block of code is a reduction in strength time optimization
2328 scan = mystrstr (*mangled, "__"); */
2334 scan = strchr (scan, '_');
2335 } while (scan != NULL && *++scan != '_');
2337 if (scan != NULL) --scan;
2342 /* We found a sequence of two or more '_', ensure that we start at
2343 the last pair in the sequence. */
2344 i = strspn (scan, "_");
2355 else if (work -> static_type)
2357 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2362 else if ((scan == *mangled)
2363 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2364 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2366 /* The ARM says nothing about the mangling of local variables.
2367 But cfront mangles local variables by prepending __<nesting_level>
2368 to them. As an extension to ARM demangling we handle this case. */
2369 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2370 && isdigit ((unsigned char)scan[2]))
2372 *mangled = scan + 2;
2373 consume_count (mangled);
2374 string_append (declp, *mangled);
2375 *mangled += strlen (*mangled);
2380 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2381 names like __Q2_3foo3bar for nested type names. So don't accept
2382 this style of constructor for cfront demangling. A GNU
2383 style member-template constructor starts with 'H'. */
2384 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2385 work -> constructor += 1;
2386 *mangled = scan + 2;
2389 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2391 /* Cfront-style parameterized type. Handled later as a signature. */
2395 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2397 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2398 || (scan[2] == 'p' && scan[3] == 's')
2399 || (scan[2] == 'p' && scan[3] == 't')))
2401 /* EDG-style parameterized type. Handled later as a signature. */
2405 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2407 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2408 && (scan[2] != 't'))
2410 /* Mangled name starts with "__". Skip over any leading '_' characters,
2411 then find the next "__" that separates the prefix from the signature.
2413 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2414 || (arm_special (mangled, declp) == 0))
2416 while (*scan == '_')
2420 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2422 /* No separator (I.E. "__not_mangled"), or empty signature
2423 (I.E. "__not_mangled_either__") */
2430 /* Look for the LAST occurrence of __, allowing names to
2431 have the '__' sequence embedded in them. */
2432 if (!(ARM_DEMANGLING || HP_DEMANGLING))
2434 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
2437 if (*(scan + 2) == '\0')
2440 demangle_function_name (work, mangled, declp, scan);
2444 else if (*(scan + 2) != '\0')
2446 /* Mangled name does not start with "__" but does have one somewhere
2447 in there with non empty stuff after it. Looks like a global
2449 demangle_function_name (work, mangled, declp, scan);
2453 /* Doesn't look like a mangled name */
2457 if (!success && (work->constructor == 2 || work->destructor == 2))
2459 string_append (declp, *mangled);
2460 *mangled += strlen (*mangled);
2470 gnu_special -- special handling of gnu mangled strings
2475 gnu_special (struct work_stuff *work, const char **mangled,
2481 Process some special GNU style mangling forms that don't fit
2482 the normal pattern. For example:
2484 _$_3foo (destructor for class foo)
2485 _vt$foo (foo virtual table)
2486 _vt$foo$bar (foo::bar virtual table)
2487 __vt_foo (foo virtual table, new style with thunks)
2488 _3foo$varname (static data member)
2489 _Q22rs2tu$vw (static data member)
2490 __t6vector1Zii (constructor with template)
2491 __thunk_4__$_7ostream (virtual function thunk)
2495 gnu_special (work, mangled, declp)
2496 struct work_stuff *work;
2497 const char **mangled;
2504 if ((*mangled)[0] == '_'
2505 && strchr (cplus_markers, (*mangled)[1]) != NULL
2506 && (*mangled)[2] == '_')
2508 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2510 work -> destructor += 1;
2512 else if ((*mangled)[0] == '_'
2513 && (((*mangled)[1] == '_'
2514 && (*mangled)[2] == 'v'
2515 && (*mangled)[3] == 't'
2516 && (*mangled)[4] == '_')
2517 || ((*mangled)[1] == 'v'
2518 && (*mangled)[2] == 't'
2519 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2521 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2522 and create the decl. Note that we consume the entire mangled
2523 input string, which means that demangle_signature has no work
2525 if ((*mangled)[2] == 'v')
2526 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2528 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2529 while (**mangled != '\0')
2535 success = demangle_qualified (work, mangled, declp, 0, 1);
2538 success = demangle_template (work, mangled, declp, 0, 1,
2542 if (isdigit((unsigned char)*mangled[0]))
2544 n = consume_count(mangled);
2545 /* We may be seeing a too-large size, or else a
2546 ".<digits>" indicating a static local symbol. In
2547 any case, declare victory and move on; *don't* try
2548 to use n to allocate. */
2549 if (n > (int) strlen (*mangled))
2557 n = strcspn (*mangled, cplus_markers);
2559 string_appendn (declp, *mangled, n);
2563 p = strpbrk (*mangled, cplus_markers);
2564 if (success && ((p == NULL) || (p == *mangled)))
2568 string_append (declp, SCOPE_STRING (work));
2579 string_append (declp, " virtual table");
2581 else if ((*mangled)[0] == '_'
2582 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2583 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2585 /* static data member, "_3foo$varname" for example */
2591 success = demangle_qualified (work, mangled, declp, 0, 1);
2594 success = demangle_template (work, mangled, declp, 0, 1, 1);
2597 n = consume_count (mangled);
2598 if (n < 0 || n > (long) strlen (*mangled))
2603 string_appendn (declp, *mangled, n);
2606 if (success && (p == *mangled))
2608 /* Consumed everything up to the cplus_marker, append the
2611 string_append (declp, SCOPE_STRING (work));
2612 n = strlen (*mangled);
2613 string_appendn (declp, *mangled, n);
2621 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2626 delta = consume_count (mangled);
2631 char *method = internal_cplus_demangle (work, ++*mangled);
2636 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2637 string_append (declp, buf);
2638 string_append (declp, method);
2640 n = strlen (*mangled);
2649 else if (strncmp (*mangled, "__t", 3) == 0
2650 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2652 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2658 success = demangle_qualified (work, mangled, declp, 0, 1);
2661 success = demangle_template (work, mangled, declp, 0, 1, 1);
2664 success = demangle_fund_type (work, mangled, declp);
2667 if (success && **mangled != '\0')
2670 string_append (declp, p);
2680 recursively_demangle(work, mangled, result, namelength)
2681 struct work_stuff *work;
2682 const char **mangled;
2686 char * recurse = (char *)NULL;
2687 char * recurse_dem = (char *)NULL;
2689 recurse = (char *) xmalloc (namelength + 1);
2690 memcpy (recurse, *mangled, namelength);
2691 recurse[namelength] = '\000';
2693 recurse_dem = cplus_demangle (recurse, work->options);
2697 string_append (result, recurse_dem);
2702 string_appendn (result, *mangled, namelength);
2705 *mangled += namelength;
2712 arm_special -- special handling of ARM/lucid mangled strings
2717 arm_special (const char **mangled,
2723 Process some special ARM style mangling forms that don't fit
2724 the normal pattern. For example:
2726 __vtbl__3foo (foo virtual table)
2727 __vtbl__3foo__3bar (bar::foo virtual table)
2732 arm_special (mangled, declp)
2733 const char **mangled;
2740 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2742 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2743 and create the decl. Note that we consume the entire mangled
2744 input string, which means that demangle_signature has no work
2746 scan = *mangled + ARM_VTABLE_STRLEN;
2747 while (*scan != '\0') /* first check it can be demangled */
2749 n = consume_count (&scan);
2752 return (0); /* no good */
2755 if (scan[0] == '_' && scan[1] == '_')
2760 (*mangled) += ARM_VTABLE_STRLEN;
2761 while (**mangled != '\0')
2763 n = consume_count (mangled);
2765 || n > (long) strlen (*mangled))
2767 string_prependn (declp, *mangled, n);
2769 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2771 string_prepend (declp, "::");
2775 string_append (declp, " virtual table");
2788 demangle_qualified -- demangle 'Q' qualified name strings
2793 demangle_qualified (struct work_stuff *, const char *mangled,
2794 string *result, int isfuncname, int append);
2798 Demangle a qualified name, such as "Q25Outer5Inner" which is
2799 the mangled form of "Outer::Inner". The demangled output is
2800 prepended or appended to the result string according to the
2801 state of the append flag.
2803 If isfuncname is nonzero, then the qualified name we are building
2804 is going to be used as a member function name, so if it is a
2805 constructor or destructor function, append an appropriate
2806 constructor or destructor name. I.E. for the above example,
2807 the result for use as a constructor is "Outer::Inner::Inner"
2808 and the result for use as a destructor is "Outer::Inner::~Inner".
2812 Numeric conversion is ASCII dependent (FIXME).
2817 demangle_qualified (work, mangled, result, isfuncname, append)
2818 struct work_stuff *work;
2819 const char **mangled;
2829 int bindex = register_Btype (work);
2831 /* We only make use of ISFUNCNAME if the entity is a constructor or
2833 isfuncname = (isfuncname
2834 && ((work->constructor & 1) || (work->destructor & 1)));
2836 string_init (&temp);
2837 string_init (&last_name);
2839 if ((*mangled)[0] == 'K')
2841 /* Squangling qualified name reuse */
2844 idx = consume_count_with_underscores (mangled);
2845 if (idx == -1 || idx >= work -> numk)
2848 string_append (&temp, work -> ktypevec[idx]);
2851 switch ((*mangled)[1])
2854 /* GNU mangled name with more than 9 classes. The count is preceded
2855 by an underscore (to distinguish it from the <= 9 case) and followed
2856 by an underscore. */
2858 qualifiers = consume_count_with_underscores (mangled);
2859 if (qualifiers == -1)
2872 /* The count is in a single digit. */
2873 num[0] = (*mangled)[1];
2875 qualifiers = atoi (num);
2877 /* If there is an underscore after the digit, skip it. This is
2878 said to be for ARM-qualified names, but the ARM makes no
2879 mention of such an underscore. Perhaps cfront uses one. */
2880 if ((*mangled)[2] == '_')
2895 /* Pick off the names and collect them in the temp buffer in the order
2896 in which they are found, separated by '::'. */
2898 while (qualifiers-- > 0)
2901 string_clear (&last_name);
2903 if (*mangled[0] == '_')
2906 if (*mangled[0] == 't')
2908 /* Here we always append to TEMP since we will want to use
2909 the template name without the template parameters as a
2910 constructor or destructor name. The appropriate
2911 (parameter-less) value is returned by demangle_template
2912 in LAST_NAME. We do not remember the template type here,
2913 in order to match the G++ mangling algorithm. */
2914 success = demangle_template(work, mangled, &temp,
2919 else if (*mangled[0] == 'K')
2923 idx = consume_count_with_underscores (mangled);
2924 if (idx == -1 || idx >= work->numk)
2927 string_append (&temp, work->ktypevec[idx]);
2930 if (!success) break;
2937 /* Now recursively demangle the qualifier
2938 * This is necessary to deal with templates in
2939 * mangling styles like EDG */
2940 namelength = consume_count (mangled);
2941 if (namelength == -1)
2946 recursively_demangle(work, mangled, &temp, namelength);
2950 success = do_type (work, mangled, &last_name);
2953 string_appends (&temp, &last_name);
2958 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2961 string_append (&temp, SCOPE_STRING (work));
2964 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2966 /* If we are using the result as a function name, we need to append
2967 the appropriate '::' separated constructor or destructor name.
2968 We do this here because this is the most convenient place, where
2969 we already have a pointer to the name and the length of the name. */
2973 string_append (&temp, SCOPE_STRING (work));
2974 if (work -> destructor & 1)
2975 string_append (&temp, "~");
2976 string_appends (&temp, &last_name);
2979 /* Now either prepend the temp buffer to the result, or append it,
2980 depending upon the state of the append flag. */
2983 string_appends (result, &temp);
2986 if (!STRING_EMPTY (result))
2987 string_append (&temp, SCOPE_STRING (work));
2988 string_prepends (result, &temp);
2991 string_delete (&last_name);
2992 string_delete (&temp);
3000 get_count -- convert an ascii count to integer, consuming tokens
3005 get_count (const char **type, int *count)
3009 Assume that *type points at a count in a mangled name; set
3010 *count to its value, and set *type to the next character after
3011 the count. There are some weird rules in effect here.
3013 If *type does not point at a string of digits, return zero.
3015 If *type points at a string of digits followed by an
3016 underscore, set *count to their value as an integer, advance
3017 *type to point *after the underscore, and return 1.
3019 If *type points at a string of digits not followed by an
3020 underscore, consume only the first digit. Set *count to its
3021 value as an integer, leave *type pointing after that digit,
3024 The excuse for this odd behavior: in the ARM and HP demangling
3025 styles, a type can be followed by a repeat count of the form
3028 `x' is a single digit specifying how many additional copies
3029 of the type to append to the argument list, and
3031 `y' is one or more digits, specifying the zero-based index of
3032 the first repeated argument in the list. Yes, as you're
3033 unmangling the name you can figure this out yourself, but
3036 So, for example, in `bar__3fooFPiN51', the first argument is a
3037 pointer to an integer (`Pi'), and then the next five arguments
3038 are the same (`N5'), and the first repeat is the function's
3039 second argument (`1').
3043 get_count (type, count)
3050 if (!isdigit ((unsigned char)**type))
3054 *count = **type - '0';
3056 if (isdigit ((unsigned char)**type))
3066 while (isdigit ((unsigned char)*p));
3077 /* RESULT will be initialised here; it will be freed on failure. The
3078 value returned is really a type_kind_t. */
3081 do_type (work, mangled, result)
3082 struct work_stuff *work;
3083 const char **mangled;
3090 const char *remembered_type;
3093 type_kind_t tk = tk_none;
3095 string_init (&btype);
3096 string_init (&decl);
3097 string_init (result);
3101 while (success && !done)
3107 /* A pointer type */
3111 if (! (work -> options & DMGL_JAVA))
3112 string_prepend (&decl, "*");
3117 /* A reference type */
3120 string_prepend (&decl, "&");
3129 if (!STRING_EMPTY (&decl)
3130 && (decl.b[0] == '*' || decl.b[0] == '&'))
3132 string_prepend (&decl, "(");
3133 string_append (&decl, ")");
3135 string_append (&decl, "[");
3136 if (**mangled != '_')
3137 success = demangle_template_value_parm (work, mangled, &decl,
3139 if (**mangled == '_')
3141 string_append (&decl, "]");
3145 /* A back reference to a previously seen type */
3148 if (!get_count (mangled, &n) || n >= work -> ntypes)
3154 remembered_type = work -> typevec[n];
3155 mangled = &remembered_type;
3162 if (!STRING_EMPTY (&decl)
3163 && (decl.b[0] == '*' || decl.b[0] == '&'))
3165 string_prepend (&decl, "(");
3166 string_append (&decl, ")");
3168 /* After picking off the function args, we expect to either find the
3169 function return type (preceded by an '_') or the end of the
3171 if (!demangle_nested_args (work, mangled, &decl)
3172 || (**mangled != '_' && **mangled != '\0'))
3177 if (success && (**mangled == '_'))
3184 type_quals = TYPE_UNQUALIFIED;
3186 member = **mangled == 'M';
3189 string_append (&decl, ")");
3191 /* We don't need to prepend `::' for a qualified name;
3192 demangle_qualified will do that for us. */
3193 if (**mangled != 'Q')
3194 string_prepend (&decl, SCOPE_STRING (work));
3196 if (isdigit ((unsigned char)**mangled))
3198 n = consume_count (mangled);
3200 || (int) strlen (*mangled) < n)
3205 string_prependn (&decl, *mangled, n);
3208 else if (**mangled == 'X' || **mangled == 'Y')
3211 do_type (work, mangled, &temp);
3212 string_prepends (&decl, &temp);
3214 else if (**mangled == 't')
3217 string_init (&temp);
3218 success = demangle_template (work, mangled, &temp,
3222 string_prependn (&decl, temp.b, temp.p - temp.b);
3223 string_clear (&temp);
3228 else if (**mangled == 'Q')
3230 success = demangle_qualified (work, mangled, &decl,
3242 string_prepend (&decl, "(");
3250 type_quals |= code_for_qualifier (**mangled);
3258 if (*(*mangled)++ != 'F')
3264 if ((member && !demangle_nested_args (work, mangled, &decl))
3265 || **mangled != '_')
3271 if (! PRINT_ANSI_QUALIFIERS)
3275 if (type_quals != TYPE_UNQUALIFIED)
3277 APPEND_BLANK (&decl);
3278 string_append (&decl, qualifier_string (type_quals));
3289 if (PRINT_ANSI_QUALIFIERS)
3291 if (!STRING_EMPTY (&decl))
3292 string_prepend (&decl, " ");
3294 string_prepend (&decl, demangle_qualifier (**mangled));
3309 if (success) switch (**mangled)
3311 /* A qualified name, such as "Outer::Inner". */
3315 success = demangle_qualified (work, mangled, result, 0, 1);
3319 /* A back reference to a previously seen squangled type */
3322 if (!get_count (mangled, &n) || n >= work -> numb)
3325 string_append (result, work->btypevec[n]);
3330 /* A template parm. We substitute the corresponding argument. */
3335 idx = consume_count_with_underscores (mangled);
3338 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3339 || consume_count_with_underscores (mangled) == -1)
3345 if (work->tmpl_argvec)
3346 string_append (result, work->tmpl_argvec[idx]);
3348 string_append_template_idx (result, idx);
3355 success = demangle_fund_type (work, mangled, result);
3357 tk = (type_kind_t) success;
3363 if (!STRING_EMPTY (&decl))
3365 string_append (result, " ");
3366 string_appends (result, &decl);
3370 string_delete (result);
3371 string_delete (&decl);
3374 /* Assume an integral type, if we're not sure. */
3375 return (int) ((tk == tk_none) ? tk_integral : tk);
3380 /* Given a pointer to a type string that represents a fundamental type
3381 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3382 string in which the demangled output is being built in RESULT, and
3383 the WORK structure, decode the types and add them to the result.
3388 "Sl" => "signed long"
3389 "CUs" => "const unsigned short"
3391 The value returned is really a type_kind_t. */
3394 demangle_fund_type (work, mangled, result)
3395 struct work_stuff *work;
3396 const char **mangled;
3404 type_kind_t tk = tk_integral;
3406 string_init (&btype);
3408 /* First pick off any type qualifiers. There can be more than one. */
3417 if (PRINT_ANSI_QUALIFIERS)
3419 if (!STRING_EMPTY (result))
3420 string_prepend (result, " ");
3421 string_prepend (result, demangle_qualifier (**mangled));
3427 APPEND_BLANK (result);
3428 string_append (result, "unsigned");
3430 case 'S': /* signed char only */
3432 APPEND_BLANK (result);
3433 string_append (result, "signed");
3437 APPEND_BLANK (result);
3438 string_append (result, "__complex");
3446 /* Now pick off the fundamental type. There can be only one. */
3455 APPEND_BLANK (result);
3456 string_append (result, "void");
3460 APPEND_BLANK (result);
3461 string_append (result, "long long");
3465 APPEND_BLANK (result);
3466 string_append (result, "long");
3470 APPEND_BLANK (result);
3471 string_append (result, "int");
3475 APPEND_BLANK (result);
3476 string_append (result, "short");
3480 APPEND_BLANK (result);
3481 string_append (result, "bool");
3486 APPEND_BLANK (result);
3487 string_append (result, "char");
3492 APPEND_BLANK (result);
3493 string_append (result, "wchar_t");
3498 APPEND_BLANK (result);
3499 string_append (result, "long double");
3504 APPEND_BLANK (result);
3505 string_append (result, "double");
3510 APPEND_BLANK (result);
3511 string_append (result, "float");
3516 if (!isdigit ((unsigned char)**mangled))
3523 if (**mangled == '_')
3528 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3531 if (**mangled != '_')
3541 strncpy (buf, *mangled, 2);
3543 *mangled += min (strlen (*mangled), 2);
3545 sscanf (buf, "%x", &dec);
3546 sprintf (buf, "int%i_t", dec);
3547 APPEND_BLANK (result);
3548 string_append (result, buf);
3552 /* An explicit type, such as "6mytype" or "7integer" */
3564 int bindex = register_Btype (work);
3566 string_init (&btype);
3567 if (demangle_class_name (work, mangled, &btype)) {
3568 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3569 APPEND_BLANK (result);
3570 string_appends (result, &btype);
3574 string_delete (&btype);
3579 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3580 string_appends (result, &btype);
3588 return success ? ((int) tk) : 0;
3592 /* Handle a template's value parameter for HP aCC (extension from ARM)
3593 **mangled points to 'S' or 'U' */
3596 do_hpacc_template_const_value (work, mangled, result)
3597 struct work_stuff *work ATTRIBUTE_UNUSED;
3598 const char **mangled;
3603 if (**mangled != 'U' && **mangled != 'S')
3606 unsigned_const = (**mangled == 'U');
3613 string_append (result, "-");
3619 /* special case for -2^31 */
3620 string_append (result, "-2147483648");
3627 /* We have to be looking at an integer now */
3628 if (!(isdigit ((unsigned char)**mangled)))
3631 /* We only deal with integral values for template
3632 parameters -- so it's OK to look only for digits */
3633 while (isdigit ((unsigned char)**mangled))
3635 char_str[0] = **mangled;
3636 string_append (result, char_str);
3641 string_append (result, "U");
3643 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3644 with L or LL suffixes. pai/1997-09-03 */
3646 return 1; /* success */
3649 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3650 **mangled is pointing to the 'A' */
3653 do_hpacc_template_literal (work, mangled, result)
3654 struct work_stuff *work;
3655 const char **mangled;
3658 int literal_len = 0;
3662 if (**mangled != 'A')
3667 literal_len = consume_count (mangled);
3669 if (literal_len <= 0)
3672 /* Literal parameters are names of arrays, functions, etc. and the
3673 canonical representation uses the address operator */
3674 string_append (result, "&");
3676 /* Now recursively demangle the literal name */
3677 recurse = (char *) xmalloc (literal_len + 1);
3678 memcpy (recurse, *mangled, literal_len);
3679 recurse[literal_len] = '\000';
3681 recurse_dem = cplus_demangle (recurse, work->options);
3685 string_append (result, recurse_dem);
3690 string_appendn (result, *mangled, literal_len);
3692 (*mangled) += literal_len;
3699 snarf_numeric_literal (args, arg)
3706 string_append (arg, char_str);
3709 else if (**args == '+')
3712 if (!isdigit ((unsigned char)**args))
3715 while (isdigit ((unsigned char)**args))
3717 char_str[0] = **args;
3718 string_append (arg, char_str);
3725 /* Demangle the next argument, given by MANGLED into RESULT, which
3726 *should be an uninitialized* string. It will be initialized here,
3727 and free'd should anything go wrong. */
3730 do_arg (work, mangled, result)
3731 struct work_stuff *work;
3732 const char **mangled;
3735 /* Remember where we started so that we can record the type, for
3736 non-squangling type remembering. */
3737 const char *start = *mangled;
3739 string_init (result);
3741 if (work->nrepeats > 0)
3745 if (work->previous_argument == 0)
3748 /* We want to reissue the previous type in this argument list. */
3749 string_appends (result, work->previous_argument);
3753 if (**mangled == 'n')
3755 /* A squangling-style repeat. */
3757 work->nrepeats = consume_count(mangled);
3759 if (work->nrepeats <= 0)
3760 /* This was not a repeat count after all. */
3763 if (work->nrepeats > 9)
3765 if (**mangled != '_')
3766 /* The repeat count should be followed by an '_' in this
3773 /* Now, the repeat is all set up. */
3774 return do_arg (work, mangled, result);
3777 /* Save the result in WORK->previous_argument so that we can find it
3778 if it's repeated. Note that saving START is not good enough: we
3779 do not want to add additional types to the back-referenceable
3780 type vector when processing a repeated type. */
3781 if (work->previous_argument)
3782 string_clear (work->previous_argument);
3785 work->previous_argument = (string*) xmalloc (sizeof (string));
3786 string_init (work->previous_argument);
3789 if (!do_type (work, mangled, work->previous_argument))
3792 string_appends (result, work->previous_argument);
3794 remember_type (work, start, *mangled - start);
3799 remember_type (work, start, len)
3800 struct work_stuff *work;
3806 if (work->forgetting_types)
3809 if (work -> ntypes >= work -> typevec_size)
3811 if (work -> typevec_size == 0)
3813 work -> typevec_size = 3;
3815 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3819 work -> typevec_size *= 2;
3821 = (char **) xrealloc ((char *)work -> typevec,
3822 sizeof (char *) * work -> typevec_size);
3825 tem = xmalloc (len + 1);
3826 memcpy (tem, start, len);
3828 work -> typevec[work -> ntypes++] = tem;
3832 /* Remember a K type class qualifier. */
3834 remember_Ktype (work, start, len)
3835 struct work_stuff *work;
3841 if (work -> numk >= work -> ksize)
3843 if (work -> ksize == 0)
3847 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3853 = (char **) xrealloc ((char *)work -> ktypevec,
3854 sizeof (char *) * work -> ksize);
3857 tem = xmalloc (len + 1);
3858 memcpy (tem, start, len);
3860 work -> ktypevec[work -> numk++] = tem;
3863 /* Register a B code, and get an index for it. B codes are registered
3864 as they are seen, rather than as they are completed, so map<temp<char> >
3865 registers map<temp<char> > as B0, and temp<char> as B1 */
3868 register_Btype (work)
3869 struct work_stuff *work;
3873 if (work -> numb >= work -> bsize)
3875 if (work -> bsize == 0)
3879 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3885 = (char **) xrealloc ((char *)work -> btypevec,
3886 sizeof (char *) * work -> bsize);
3889 ret = work -> numb++;
3890 work -> btypevec[ret] = NULL;
3894 /* Store a value into a previously registered B code type. */
3897 remember_Btype (work, start, len, index)
3898 struct work_stuff *work;
3904 tem = xmalloc (len + 1);
3905 memcpy (tem, start, len);
3907 work -> btypevec[index] = tem;
3910 /* Lose all the info related to B and K type codes. */
3912 forget_B_and_K_types (work)
3913 struct work_stuff *work;
3917 while (work -> numk > 0)
3919 i = --(work -> numk);
3920 if (work -> ktypevec[i] != NULL)
3922 free (work -> ktypevec[i]);
3923 work -> ktypevec[i] = NULL;
3927 while (work -> numb > 0)
3929 i = --(work -> numb);
3930 if (work -> btypevec[i] != NULL)
3932 free (work -> btypevec[i]);
3933 work -> btypevec[i] = NULL;
3937 /* Forget the remembered types, but not the type vector itself. */
3941 struct work_stuff *work;
3945 while (work -> ntypes > 0)
3947 i = --(work -> ntypes);
3948 if (work -> typevec[i] != NULL)
3950 free (work -> typevec[i]);
3951 work -> typevec[i] = NULL;
3956 /* Process the argument list part of the signature, after any class spec
3957 has been consumed, as well as the first 'F' character (if any). For
3960 "__als__3fooRT0" => process "RT0"
3961 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3963 DECLP must be already initialised, usually non-empty. It won't be freed
3966 Note that g++ differs significantly from ARM and lucid style mangling
3967 with regards to references to previously seen types. For example, given
3968 the source fragment:
3972 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3975 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3976 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3978 g++ produces the names:
3983 while lcc (and presumably other ARM style compilers as well) produces:
3985 foo__FiR3fooT1T2T1T2
3986 __ct__3fooFiR3fooT1T2T1T2
3988 Note that g++ bases its type numbers starting at zero and counts all
3989 previously seen types, while lucid/ARM bases its type numbers starting
3990 at one and only considers types after it has seen the 'F' character
3991 indicating the start of the function args. For lucid/ARM style, we
3992 account for this difference by discarding any previously seen types when
3993 we see the 'F' character, and subtracting one from the type number
3999 demangle_args (work, mangled, declp)
4000 struct work_stuff *work;
4001 const char **mangled;
4011 if (PRINT_ARG_TYPES)
4013 string_append (declp, "(");
4014 if (**mangled == '\0')
4016 string_append (declp, "void");
4020 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4021 || work->nrepeats > 0)
4023 if ((**mangled == 'N') || (**mangled == 'T'))
4025 temptype = *(*mangled)++;
4027 if (temptype == 'N')
4029 if (!get_count (mangled, &r))
4038 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4040 /* If we have 10 or more types we might have more than a 1 digit
4041 index so we'll have to consume the whole count here. This
4042 will lose if the next thing is a type name preceded by a
4043 count but it's impossible to demangle that case properly
4044 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4045 Pc, ...)" or "(..., type12, char *, ...)" */
4046 if ((t = consume_count(mangled)) <= 0)
4053 if (!get_count (mangled, &t))
4058 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4062 /* Validate the type index. Protect against illegal indices from
4063 malformed type strings. */
4064 if ((t < 0) || (t >= work -> ntypes))
4068 while (work->nrepeats > 0 || --r >= 0)
4070 tem = work -> typevec[t];
4071 if (need_comma && PRINT_ARG_TYPES)
4073 string_append (declp, ", ");
4075 if (!do_arg (work, &tem, &arg))
4079 if (PRINT_ARG_TYPES)
4081 string_appends (declp, &arg);
4083 string_delete (&arg);
4089 if (need_comma && PRINT_ARG_TYPES)
4090 string_append (declp, ", ");
4091 if (!do_arg (work, mangled, &arg))
4093 if (PRINT_ARG_TYPES)
4094 string_appends (declp, &arg);
4095 string_delete (&arg);
4100 if (**mangled == 'e')
4103 if (PRINT_ARG_TYPES)
4107 string_append (declp, ",");
4109 string_append (declp, "...");
4113 if (PRINT_ARG_TYPES)
4115 string_append (declp, ")");
4120 /* Like demangle_args, but for demangling the argument lists of function
4121 and method pointers or references, not top-level declarations. */
4124 demangle_nested_args (work, mangled, declp)
4125 struct work_stuff *work;
4126 const char **mangled;
4129 string* saved_previous_argument;
4133 /* The G++ name-mangling algorithm does not remember types on nested
4134 argument lists, unless -fsquangling is used, and in that case the
4135 type vector updated by remember_type is not used. So, we turn
4136 off remembering of types here. */
4137 ++work->forgetting_types;
4139 /* For the repeat codes used with -fsquangling, we must keep track of
4140 the last argument. */
4141 saved_previous_argument = work->previous_argument;
4142 saved_nrepeats = work->nrepeats;
4143 work->previous_argument = 0;
4146 /* Actually demangle the arguments. */
4147 result = demangle_args (work, mangled, declp);
4149 /* Restore the previous_argument field. */
4150 if (work->previous_argument)
4151 string_delete (work->previous_argument);
4152 work->previous_argument = saved_previous_argument;
4153 --work->forgetting_types;
4154 work->nrepeats = saved_nrepeats;
4160 demangle_function_name (work, mangled, declp, scan)
4161 struct work_stuff *work;
4162 const char **mangled;
4170 string_appendn (declp, (*mangled), scan - (*mangled));
4171 string_need (declp, 1);
4172 *(declp -> p) = '\0';
4174 /* Consume the function name, including the "__" separating the name
4175 from the signature. We are guaranteed that SCAN points to the
4178 (*mangled) = scan + 2;
4179 /* We may be looking at an instantiation of a template function:
4180 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4181 following _F marks the start of the function arguments. Handle
4182 the template arguments first. */
4184 if (HP_DEMANGLING && (**mangled == 'X'))
4186 demangle_arm_hp_template (work, mangled, 0, declp);
4187 /* This leaves MANGLED pointing to the 'F' marking func args */
4190 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4193 /* See if we have an ARM style constructor or destructor operator.
4194 If so, then just record it, clear the decl, and return.
4195 We can't build the actual constructor/destructor decl until later,
4196 when we recover the class name from the signature. */
4198 if (strcmp (declp -> b, "__ct") == 0)
4200 work -> constructor += 1;
4201 string_clear (declp);
4204 else if (strcmp (declp -> b, "__dt") == 0)
4206 work -> destructor += 1;
4207 string_clear (declp);
4212 if (declp->p - declp->b >= 3
4213 && declp->b[0] == 'o'
4214 && declp->b[1] == 'p'
4215 && strchr (cplus_markers, declp->b[2]) != NULL)
4217 /* see if it's an assignment expression */
4218 if (declp->p - declp->b >= 10 /* op$assign_ */
4219 && memcmp (declp->b + 3, "assign_", 7) == 0)
4221 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4223 int len = declp->p - declp->b - 10;
4224 if ((int) strlen (optable[i].in) == len
4225 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4227 string_clear (declp);
4228 string_append (declp, "operator");
4229 string_append (declp, optable[i].out);
4230 string_append (declp, "=");
4237 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4239 int len = declp->p - declp->b - 3;
4240 if ((int) strlen (optable[i].in) == len
4241 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4243 string_clear (declp);
4244 string_append (declp, "operator");
4245 string_append (declp, optable[i].out);
4251 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4252 && strchr (cplus_markers, declp->b[4]) != NULL)
4254 /* type conversion operator */
4256 if (do_type (work, &tem, &type))
4258 string_clear (declp);
4259 string_append (declp, "operator ");
4260 string_appends (declp, &type);
4261 string_delete (&type);
4264 else if (declp->b[0] == '_' && declp->b[1] == '_'
4265 && declp->b[2] == 'o' && declp->b[3] == 'p')
4268 /* type conversion operator. */
4270 if (do_type (work, &tem, &type))
4272 string_clear (declp);
4273 string_append (declp, "operator ");
4274 string_appends (declp, &type);
4275 string_delete (&type);
4278 else if (declp->b[0] == '_' && declp->b[1] == '_'
4279 && islower((unsigned char)declp->b[2])
4280 && islower((unsigned char)declp->b[3]))
4282 if (declp->b[4] == '\0')
4285 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4287 if (strlen (optable[i].in) == 2
4288 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4290 string_clear (declp);
4291 string_append (declp, "operator");
4292 string_append (declp, optable[i].out);
4299 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4302 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4304 if (strlen (optable[i].in) == 3
4305 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4307 string_clear (declp);
4308 string_append (declp, "operator");
4309 string_append (declp, optable[i].out);
4318 /* a mini string-handling package */
4333 s->p = s->b = xmalloc (n);
4336 else if (s->e - s->p < n)
4341 s->b = xrealloc (s->b, n);
4354 s->b = s->e = s->p = NULL;
4362 s->b = s->p = s->e = NULL;
4378 return (s->b == s->p);
4384 string_append (p, s)
4389 if (s == NULL || *s == '\0')
4393 memcpy (p->p, s, n);
4398 string_appends (p, s)
4407 memcpy (p->p, s->b, n);
4413 string_appendn (p, s, n)
4421 memcpy (p->p, s, n);
4427 string_prepend (p, s)
4431 if (s != NULL && *s != '\0')
4433 string_prependn (p, s, strlen (s));
4438 string_prepends (p, s)
4443 string_prependn (p, s->b, s->p - s->b);
4448 string_prependn (p, s, n)
4458 for (q = p->p - 1; q >= p->b; q--)
4462 memcpy (p->b, s, n);
4468 string_append_template_idx (s, idx)
4472 char buf[INTBUF_SIZE + 1 /* 'T' */];
4473 sprintf(buf, "T%d", idx);
4474 string_append (s, buf);
4477 /* To generate a standalone demangler program for testing purposes,
4478 just compile and link this file with -DMAIN and libiberty.a. When
4479 run, it demangles each command line arg, or each stdin string, and
4480 prints the result on stdout. */
4486 static const char *program_name;
4487 static const char *program_version = VERSION;
4488 static int flags = DMGL_PARAMS | DMGL_ANSI;
4490 static void demangle_it PARAMS ((char *));
4491 static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
4492 static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
4493 static void print_demangler_list PARAMS ((FILE *));
4496 demangle_it (mangled_name)
4501 result = cplus_demangle (mangled_name, flags);
4504 printf ("%s\n", mangled_name);
4508 printf ("%s\n", result);
4514 print_demangler_list (stream)
4517 struct demangler_engine *demangler;
4519 fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
4521 for (demangler = libiberty_demanglers + 1;
4522 demangler->demangling_style != unknown_demangling;
4524 fprintf (stream, ",%s", demangler->demangling_style_name);
4526 fprintf (stream, "}");
4530 usage (stream, status)
4535 Usage: %s [-_] [-n] [--strip-underscores] [--no-strip-underscores] \n",
4540 print_demangler_list (stream);
4541 fprintf (stream, "]\n");
4545 print_demangler_list (stream);
4546 fprintf (stream, "]\n");
4549 [--help] [--version] [arg...]\n");
4553 #define MBUF_SIZE 32767
4554 char mbuffer[MBUF_SIZE];
4556 /* Defined in the automatically-generated underscore.c. */
4557 extern int prepends_underscore;
4559 int strip_underscore = 0;
4561 static struct option long_options[] = {
4562 {"strip-underscores", no_argument, 0, '_'},
4563 {"format", required_argument, 0, 's'},
4564 {"help", no_argument, 0, 'h'},
4565 {"java", no_argument, 0, 'j'},
4566 {"no-strip-underscores", no_argument, 0, 'n'},
4567 {"version", no_argument, 0, 'v'},
4568 {0, no_argument, 0, 0}
4571 /* More 'friendly' abort that prints the line and file.
4572 config.h can #define abort fancy_abort if you like that sort of thing. */
4577 fatal ("Internal gcc abort.");
4582 standard_symbol_characters PARAMS ((void));
4585 hp_symbol_characters PARAMS ((void));
4588 gnu_new_abi_symbol_characters PARAMS ((void));
4590 /* Return the string of non-alnum characters that may occur
4591 as a valid symbol component, in the standard assembler symbol
4595 standard_symbol_characters ()
4601 /* Return the string of non-alnum characters that may occur
4602 as a valid symbol name component in an HP object file.
4604 Note that, since HP's compiler generates object code straight from
4605 C++ source, without going through an assembler, its mangled
4606 identifiers can use all sorts of characters that no assembler would
4607 tolerate, so the alphabet this function creates is a little odd.
4608 Here are some sample mangled identifiers offered by HP:
4610 typeid*__XT24AddressIndExpClassMember_
4611 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4612 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4614 This still seems really weird to me, since nowhere else in this
4615 file is there anything to recognize curly brackets, parens, etc.
4616 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4617 this is right, but I still strongly suspect that there's a
4618 misunderstanding here.
4620 If we decide it's better for c++filt to use HP's assembler syntax
4621 to scrape identifiers out of its input, here's the definition of
4622 the symbol name syntax from the HP assembler manual:
4624 Symbols are composed of uppercase and lowercase letters, decimal
4625 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4626 underscore (_). A symbol can begin with a letter, digit underscore or
4627 dollar sign. If a symbol begins with a digit, it must contain a
4628 non-digit character.
4632 hp_symbol_characters ()
4634 return "_$.<>#,*&[]:(){}";
4638 /* Return the string of non-alnum characters that may occur
4639 as a valid symbol component in the GNU standard C++ ABI mangling
4643 gnu_new_abi_symbol_characters ()
4649 extern int main PARAMS ((int, char **));
4658 const char *valid_symbols;
4660 program_name = argv[0];
4662 strip_underscore = prepends_underscore;
4664 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4674 strip_underscore = 0;
4677 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4680 strip_underscore = 1;
4687 enum demangling_styles style;
4689 style = cplus_demangle_name_to_style (optarg);
4690 if (style == unknown_demangling)
4692 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4693 program_name, optarg);
4697 cplus_demangle_set_style (style);
4705 for ( ; optind < argc; optind++)
4707 demangle_it (argv[optind]);
4712 switch (current_demangling_style)
4714 case gnu_demangling:
4715 case lucid_demangling:
4716 case arm_demangling:
4717 case edg_demangling:
4718 valid_symbols = standard_symbol_characters ();
4721 valid_symbols = hp_symbol_characters ();
4723 case gnu_new_abi_demangling:
4724 valid_symbols = gnu_new_abi_symbol_characters ();
4727 /* Folks should explicitly indicate the appropriate alphabet for
4728 each demangling. Providing a default would allow the
4729 question to go unconsidered. */
4737 /* Try to read a label. */
4738 while (c != EOF && (isalnum (c) || strchr (valid_symbols, c)))
4740 if (i >= MBUF_SIZE-1)
4749 if (mbuffer[0] == '.')
4751 if (strip_underscore && mbuffer[skip_first] == '_')
4759 result = cplus_demangle (mbuffer + skip_first, flags);
4762 if (mbuffer[0] == '.')
4764 fputs (result, stdout);
4768 fputs (mbuffer, stdout);
4786 fprintf (stderr, "%s: %s\n", program_name, str);
4794 register PTR value = (PTR) malloc (size);
4796 fatal ("virtual memory exhausted");
4801 xrealloc (ptr, size)
4805 register PTR value = (PTR) realloc (ptr, size);
4807 fatal ("virtual memory exhausted");