1999-10-27 Andreas Jaeger <aj@suse.de>
[binutils.git] / libiberty / cplus-dem.c
blob14ef56a588df0458dee2e72faafaa1c6e5efcc59
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 static const char *mystrstr PARAMS ((const char *, const char *));
56 static const char *
57 mystrstr (s1, s2)
58 const char *s1, *s2;
60 register const char *p = s1;
61 register int len = strlen (s2);
63 for (; (p = strchr (p, *s2)) != 0; p++)
65 if (strncmp (p, s2, len) == 0)
67 return (p);
70 return (0);
73 /* In order to allow a single demangler executable to demangle strings
74 using various common values of CPLUS_MARKER, as well as any specific
75 one set at compile time, we maintain a string containing all the
76 commonly used ones, and check to see if the marker we are looking for
77 is in that string. CPLUS_MARKER is usually '$' on systems where the
78 assembler can deal with that. Where the assembler can't, it's usually
79 '.' (but on many systems '.' is used for other things). We put the
80 current defined CPLUS_MARKER first (which defaults to '$'), followed
81 by the next most common value, followed by an explicit '$' in case
82 the value of CPLUS_MARKER is not '$'.
84 We could avoid this if we could just get g++ to tell us what the actual
85 cplus marker character is as part of the debug information, perhaps by
86 ensuring that it is the character that terminates the gcc<n>_compiled
87 marker symbol (FIXME). */
89 #if !defined (CPLUS_MARKER)
90 #define CPLUS_MARKER '$'
91 #endif
93 enum demangling_styles current_demangling_style = gnu_demangling;
95 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
97 static char char_str[2] = { '\000', '\000' };
99 void
100 set_cplus_marker_for_demangling (ch)
101 int ch;
103 cplus_markers[0] = ch;
106 typedef struct string /* Beware: these aren't required to be */
107 { /* '\0' terminated. */
108 char *b; /* pointer to start of string */
109 char *p; /* pointer after last character */
110 char *e; /* pointer after end of allocated space */
111 } string;
113 /* Stuff that is shared between sub-routines.
114 Using a shared structure allows cplus_demangle to be reentrant. */
116 struct work_stuff
118 int options;
119 char **typevec;
120 char **ktypevec;
121 char **btypevec;
122 int numk;
123 int numb;
124 int ksize;
125 int bsize;
126 int ntypes;
127 int typevec_size;
128 int constructor;
129 int destructor;
130 int static_type; /* A static member function */
131 int temp_start; /* index in demangled to start of template args */
132 int type_quals; /* The type qualifiers. */
133 int dllimported; /* Symbol imported from a PE DLL */
134 char **tmpl_argvec; /* Template function arguments. */
135 int ntmpl_args; /* The number of template function arguments. */
136 int forgetting_types; /* Nonzero if we are not remembering the types
137 we see. */
138 string* previous_argument; /* The last function argument demangled. */
139 int nrepeats; /* The number of times to repeat the previous
140 argument. */
143 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
144 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
146 static const struct optable
148 const char *in;
149 const char *out;
150 int flags;
151 } optable[] = {
152 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
153 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
154 {"new", " new", 0}, /* old (1.91, and 1.x) */
155 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
156 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
157 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
158 {"as", "=", DMGL_ANSI}, /* ansi */
159 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
160 {"eq", "==", DMGL_ANSI}, /* old, ansi */
161 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
162 {"gt", ">", DMGL_ANSI}, /* old, ansi */
163 {"le", "<=", DMGL_ANSI}, /* old, ansi */
164 {"lt", "<", DMGL_ANSI}, /* old, ansi */
165 {"plus", "+", 0}, /* old */
166 {"pl", "+", DMGL_ANSI}, /* ansi */
167 {"apl", "+=", DMGL_ANSI}, /* ansi */
168 {"minus", "-", 0}, /* old */
169 {"mi", "-", DMGL_ANSI}, /* ansi */
170 {"ami", "-=", DMGL_ANSI}, /* ansi */
171 {"mult", "*", 0}, /* old */
172 {"ml", "*", DMGL_ANSI}, /* ansi */
173 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
174 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
175 {"convert", "+", 0}, /* old (unary +) */
176 {"negate", "-", 0}, /* old (unary -) */
177 {"trunc_mod", "%", 0}, /* old */
178 {"md", "%", DMGL_ANSI}, /* ansi */
179 {"amd", "%=", DMGL_ANSI}, /* ansi */
180 {"trunc_div", "/", 0}, /* old */
181 {"dv", "/", DMGL_ANSI}, /* ansi */
182 {"adv", "/=", DMGL_ANSI}, /* ansi */
183 {"truth_andif", "&&", 0}, /* old */
184 {"aa", "&&", DMGL_ANSI}, /* ansi */
185 {"truth_orif", "||", 0}, /* old */
186 {"oo", "||", DMGL_ANSI}, /* ansi */
187 {"truth_not", "!", 0}, /* old */
188 {"nt", "!", DMGL_ANSI}, /* ansi */
189 {"postincrement","++", 0}, /* old */
190 {"pp", "++", DMGL_ANSI}, /* ansi */
191 {"postdecrement","--", 0}, /* old */
192 {"mm", "--", DMGL_ANSI}, /* ansi */
193 {"bit_ior", "|", 0}, /* old */
194 {"or", "|", DMGL_ANSI}, /* ansi */
195 {"aor", "|=", DMGL_ANSI}, /* ansi */
196 {"bit_xor", "^", 0}, /* old */
197 {"er", "^", DMGL_ANSI}, /* ansi */
198 {"aer", "^=", DMGL_ANSI}, /* ansi */
199 {"bit_and", "&", 0}, /* old */
200 {"ad", "&", DMGL_ANSI}, /* ansi */
201 {"aad", "&=", DMGL_ANSI}, /* ansi */
202 {"bit_not", "~", 0}, /* old */
203 {"co", "~", DMGL_ANSI}, /* ansi */
204 {"call", "()", 0}, /* old */
205 {"cl", "()", DMGL_ANSI}, /* ansi */
206 {"alshift", "<<", 0}, /* old */
207 {"ls", "<<", DMGL_ANSI}, /* ansi */
208 {"als", "<<=", DMGL_ANSI}, /* ansi */
209 {"arshift", ">>", 0}, /* old */
210 {"rs", ">>", DMGL_ANSI}, /* ansi */
211 {"ars", ">>=", DMGL_ANSI}, /* ansi */
212 {"component", "->", 0}, /* old */
213 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
214 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
215 {"indirect", "*", 0}, /* old */
216 {"method_call", "->()", 0}, /* old */
217 {"addr", "&", 0}, /* old (unary &) */
218 {"array", "[]", 0}, /* old */
219 {"vc", "[]", DMGL_ANSI}, /* ansi */
220 {"compound", ", ", 0}, /* old */
221 {"cm", ", ", DMGL_ANSI}, /* ansi */
222 {"cond", "?:", 0}, /* old */
223 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
224 {"max", ">?", 0}, /* old */
225 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
226 {"min", "<?", 0}, /* old */
227 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
228 {"nop", "", 0}, /* old (for operator=) */
229 {"rm", "->*", DMGL_ANSI}, /* ansi */
230 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
233 /* These values are used to indicate the various type varieties.
234 They are all non-zero so that they can be used as `success'
235 values. */
236 typedef enum type_kind_t
238 tk_none,
239 tk_pointer,
240 tk_reference,
241 tk_integral,
242 tk_bool,
243 tk_char,
244 tk_real
245 } type_kind_t;
247 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
248 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
249 string_prepend(str, " ");}
250 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
251 string_append(str, " ");}
252 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
254 /* The scope separator appropriate for the language being demangled. */
256 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
258 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
259 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
261 /* Prototypes for local functions */
263 static char *
264 mop_up PARAMS ((struct work_stuff *, string *, int));
266 static void
267 squangle_mop_up PARAMS ((struct work_stuff *));
269 #if 0
270 static int
271 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
272 #endif
274 static char *
275 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
277 static int
278 demangle_template_template_parm PARAMS ((struct work_stuff *work,
279 const char **, string *));
281 static int
282 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
283 string *, int, int));
285 static int
286 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
287 const char **));
289 static int
290 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
292 static int
293 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
294 int, int));
296 static int
297 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
299 static int
300 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
302 static int
303 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
305 static int
306 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
308 static int
309 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
311 static int
312 arm_special PARAMS ((const char **, string *));
314 static void
315 string_need PARAMS ((string *, int));
317 static void
318 string_delete PARAMS ((string *));
320 static void
321 string_init PARAMS ((string *));
323 static void
324 string_clear PARAMS ((string *));
326 #if 0
327 static int
328 string_empty PARAMS ((string *));
329 #endif
331 static void
332 string_append PARAMS ((string *, const char *));
334 static void
335 string_appends PARAMS ((string *, string *));
337 static void
338 string_appendn PARAMS ((string *, const char *, int));
340 static void
341 string_prepend PARAMS ((string *, const char *));
343 static void
344 string_prependn PARAMS ((string *, const char *, int));
346 static int
347 get_count PARAMS ((const char **, int *));
349 static int
350 consume_count PARAMS ((const char **));
352 static int
353 consume_count_with_underscores PARAMS ((const char**));
355 static int
356 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
358 static int
359 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
361 static int
362 do_type PARAMS ((struct work_stuff *, const char **, string *));
364 static int
365 do_arg PARAMS ((struct work_stuff *, const char **, string *));
367 static void
368 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
369 const char *));
371 static void
372 remember_type PARAMS ((struct work_stuff *, const char *, int));
374 static void
375 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
377 static int
378 register_Btype PARAMS ((struct work_stuff *));
380 static void
381 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
383 static void
384 forget_types PARAMS ((struct work_stuff *));
386 static void
387 forget_B_and_K_types PARAMS ((struct work_stuff *));
389 static void
390 string_prepends PARAMS ((string *, string *));
392 static int
393 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
394 string*, type_kind_t));
396 static int
397 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
399 static int
400 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
402 static int
403 snarf_numeric_literal PARAMS ((const char **, string *));
405 /* There is a TYPE_QUAL value for each type qualifier. They can be
406 combined by bitwise-or to form the complete set of qualifiers for a
407 type. */
409 #define TYPE_UNQUALIFIED 0x0
410 #define TYPE_QUAL_CONST 0x1
411 #define TYPE_QUAL_VOLATILE 0x2
412 #define TYPE_QUAL_RESTRICT 0x4
414 static int
415 code_for_qualifier PARAMS ((int));
417 static const char*
418 qualifier_string PARAMS ((int));
420 static const char*
421 demangle_qualifier PARAMS ((int));
423 /* Translate count to integer, consuming tokens in the process.
424 Conversion terminates on the first non-digit character.
426 Trying to consume something that isn't a count results in no
427 consumption of input and a return of -1.
429 Overflow consumes the rest of the digits, and returns -1. */
431 static int
432 consume_count (type)
433 const char **type;
435 int count = 0;
437 if (! isdigit ((unsigned char)**type))
438 return -1;
440 while (isdigit ((unsigned char)**type))
442 count *= 10;
444 /* Check for overflow.
445 We assume that count is represented using two's-complement;
446 no power of two is divisible by ten, so if an overflow occurs
447 when multiplying by ten, the result will not be a multiple of
448 ten. */
449 if ((count % 10) != 0)
451 while (isdigit ((unsigned char) **type))
452 (*type)++;
453 return -1;
456 count += **type - '0';
457 (*type)++;
460 return (count);
464 /* Like consume_count, but for counts that are preceded and followed
465 by '_' if they are greater than 10. Also, -1 is returned for
466 failure, since 0 can be a valid value. */
468 static int
469 consume_count_with_underscores (mangled)
470 const char **mangled;
472 int idx;
474 if (**mangled == '_')
476 (*mangled)++;
477 if (!isdigit ((unsigned char)**mangled))
478 return -1;
480 idx = consume_count (mangled);
481 if (**mangled != '_')
482 /* The trailing underscore was missing. */
483 return -1;
485 (*mangled)++;
487 else
489 if (**mangled < '0' || **mangled > '9')
490 return -1;
492 idx = **mangled - '0';
493 (*mangled)++;
496 return idx;
499 /* C is the code for a type-qualifier. Return the TYPE_QUAL
500 corresponding to this qualifier. */
502 static int
503 code_for_qualifier (c)
504 int c;
506 switch (c)
508 case 'C':
509 return TYPE_QUAL_CONST;
511 case 'V':
512 return TYPE_QUAL_VOLATILE;
514 case 'u':
515 return TYPE_QUAL_RESTRICT;
517 default:
518 break;
521 /* C was an invalid qualifier. */
522 abort ();
525 /* Return the string corresponding to the qualifiers given by
526 TYPE_QUALS. */
528 static const char*
529 qualifier_string (type_quals)
530 int type_quals;
532 switch (type_quals)
534 case TYPE_UNQUALIFIED:
535 return "";
537 case TYPE_QUAL_CONST:
538 return "const";
540 case TYPE_QUAL_VOLATILE:
541 return "volatile";
543 case TYPE_QUAL_RESTRICT:
544 return "__restrict";
546 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
547 return "const volatile";
549 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
550 return "const __restrict";
552 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
553 return "volatile __restrict";
555 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
556 return "const volatile __restrict";
558 default:
559 break;
562 /* TYPE_QUALS was an invalid qualifier set. */
563 abort ();
566 /* C is the code for a type-qualifier. Return the string
567 corresponding to this qualifier. This function should only be
568 called with a valid qualifier code. */
570 static const char*
571 demangle_qualifier (c)
572 int c;
574 return qualifier_string (code_for_qualifier (c));
578 cplus_demangle_opname (opname, result, options)
579 const char *opname;
580 char *result;
581 int options;
583 int len, len1, ret;
584 string type;
585 struct work_stuff work[1];
586 const char *tem;
588 len = strlen(opname);
589 result[0] = '\0';
590 ret = 0;
591 memset ((char *) work, 0, sizeof (work));
592 work->options = options;
594 if (opname[0] == '_' && opname[1] == '_'
595 && opname[2] == 'o' && opname[3] == 'p')
597 /* ANSI. */
598 /* type conversion operator. */
599 tem = opname + 4;
600 if (do_type (work, &tem, &type))
602 strcat (result, "operator ");
603 strncat (result, type.b, type.p - type.b);
604 string_delete (&type);
605 ret = 1;
608 else if (opname[0] == '_' && opname[1] == '_'
609 && opname[2] >= 'a' && opname[2] <= 'z'
610 && opname[3] >= 'a' && opname[3] <= 'z')
612 if (opname[4] == '\0')
614 /* Operator. */
615 size_t i;
616 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
618 if (strlen (optable[i].in) == 2
619 && memcmp (optable[i].in, opname + 2, 2) == 0)
621 strcat (result, "operator");
622 strcat (result, optable[i].out);
623 ret = 1;
624 break;
628 else
630 if (opname[2] == 'a' && opname[5] == '\0')
632 /* Assignment. */
633 size_t i;
634 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
636 if (strlen (optable[i].in) == 3
637 && memcmp (optable[i].in, opname + 2, 3) == 0)
639 strcat (result, "operator");
640 strcat (result, optable[i].out);
641 ret = 1;
642 break;
648 else if (len >= 3
649 && opname[0] == 'o'
650 && opname[1] == 'p'
651 && strchr (cplus_markers, opname[2]) != NULL)
653 /* see if it's an assignment expression */
654 if (len >= 10 /* op$assign_ */
655 && memcmp (opname + 3, "assign_", 7) == 0)
657 size_t i;
658 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
660 len1 = len - 10;
661 if ((int) strlen (optable[i].in) == len1
662 && memcmp (optable[i].in, opname + 10, len1) == 0)
664 strcat (result, "operator");
665 strcat (result, optable[i].out);
666 strcat (result, "=");
667 ret = 1;
668 break;
672 else
674 size_t i;
675 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
677 len1 = len - 3;
678 if ((int) strlen (optable[i].in) == len1
679 && memcmp (optable[i].in, opname + 3, len1) == 0)
681 strcat (result, "operator");
682 strcat (result, optable[i].out);
683 ret = 1;
684 break;
689 else if (len >= 5 && memcmp (opname, "type", 4) == 0
690 && strchr (cplus_markers, opname[4]) != NULL)
692 /* type conversion operator */
693 tem = opname + 5;
694 if (do_type (work, &tem, &type))
696 strcat (result, "operator ");
697 strncat (result, type.b, type.p - type.b);
698 string_delete (&type);
699 ret = 1;
702 squangle_mop_up (work);
703 return ret;
706 /* Takes operator name as e.g. "++" and returns mangled
707 operator name (e.g. "postincrement_expr"), or NULL if not found.
709 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
710 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
712 const char *
713 cplus_mangle_opname (opname, options)
714 const char *opname;
715 int options;
717 size_t i;
718 int len;
720 len = strlen (opname);
721 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
723 if ((int) strlen (optable[i].out) == len
724 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
725 && memcmp (optable[i].out, opname, len) == 0)
726 return optable[i].in;
728 return (0);
731 /* char *cplus_demangle (const char *mangled, int options)
733 If MANGLED is a mangled function name produced by GNU C++, then
734 a pointer to a malloced string giving a C++ representation
735 of the name will be returned; otherwise NULL will be returned.
736 It is the caller's responsibility to free the string which
737 is returned.
739 The OPTIONS arg may contain one or more of the following bits:
741 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
742 included.
743 DMGL_PARAMS Function parameters are included.
745 For example,
747 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
748 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
749 cplus_demangle ("foo__1Ai", 0) => "A::foo"
751 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
752 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
753 cplus_demangle ("foo__1Afe", 0) => "A::foo"
755 Note that any leading underscores, or other such characters prepended by
756 the compilation system, are presumed to have already been stripped from
757 MANGLED. */
759 char *
760 cplus_demangle (mangled, options)
761 const char *mangled;
762 int options;
764 char *ret;
765 struct work_stuff work[1];
766 memset ((char *) work, 0, sizeof (work));
767 work -> options = options;
768 if ((work -> options & DMGL_STYLE_MASK) == 0)
769 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
771 ret = internal_cplus_demangle (work, mangled);
772 squangle_mop_up (work);
773 return (ret);
777 /* This function performs most of what cplus_demangle use to do, but
778 to be able to demangle a name with a B, K or n code, we need to
779 have a longer term memory of what types have been seen. The original
780 now intializes and cleans up the squangle code info, while internal
781 calls go directly to this routine to avoid resetting that info. */
783 static char *
784 internal_cplus_demangle (work, mangled)
785 struct work_stuff *work;
786 const char *mangled;
789 string decl;
790 int success = 0;
791 char *demangled = NULL;
792 int s1,s2,s3,s4;
793 s1 = work->constructor;
794 s2 = work->destructor;
795 s3 = work->static_type;
796 s4 = work->type_quals;
797 work->constructor = work->destructor = 0;
798 work->type_quals = TYPE_UNQUALIFIED;
799 work->dllimported = 0;
801 if ((mangled != NULL) && (*mangled != '\0'))
803 string_init (&decl);
805 /* First check to see if gnu style demangling is active and if the
806 string to be demangled contains a CPLUS_MARKER. If so, attempt to
807 recognize one of the gnu special forms rather than looking for a
808 standard prefix. In particular, don't worry about whether there
809 is a "__" string in the mangled string. Consider "_$_5__foo" for
810 example. */
812 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
814 success = gnu_special (work, &mangled, &decl);
816 if (!success)
818 success = demangle_prefix (work, &mangled, &decl);
820 if (success && (*mangled != '\0'))
822 success = demangle_signature (work, &mangled, &decl);
824 if (work->constructor == 2)
826 string_prepend (&decl, "global constructors keyed to ");
827 work->constructor = 0;
829 else if (work->destructor == 2)
831 string_prepend (&decl, "global destructors keyed to ");
832 work->destructor = 0;
834 else if (work->dllimported == 1)
836 string_prepend (&decl, "import stub for ");
837 work->dllimported = 0;
839 demangled = mop_up (work, &decl, success);
841 work->constructor = s1;
842 work->destructor = s2;
843 work->static_type = s3;
844 work->type_quals = s4;
845 return (demangled);
849 /* Clear out and squangling related storage */
850 static void
851 squangle_mop_up (work)
852 struct work_stuff *work;
854 /* clean up the B and K type mangling types. */
855 forget_B_and_K_types (work);
856 if (work -> btypevec != NULL)
858 free ((char *) work -> btypevec);
860 if (work -> ktypevec != NULL)
862 free ((char *) work -> ktypevec);
866 /* Clear out any mangled storage */
868 static char *
869 mop_up (work, declp, success)
870 struct work_stuff *work;
871 string *declp;
872 int success;
874 char *demangled = NULL;
876 /* Discard the remembered types, if any. */
878 forget_types (work);
879 if (work -> typevec != NULL)
881 free ((char *) work -> typevec);
882 work -> typevec = NULL;
883 work -> typevec_size = 0;
885 if (work->tmpl_argvec)
887 int i;
889 for (i = 0; i < work->ntmpl_args; i++)
890 if (work->tmpl_argvec[i])
891 free ((char*) work->tmpl_argvec[i]);
893 free ((char*) work->tmpl_argvec);
894 work->tmpl_argvec = NULL;
896 if (work->previous_argument)
898 string_delete (work->previous_argument);
899 free ((char*) work->previous_argument);
900 work->previous_argument = NULL;
903 /* If demangling was successful, ensure that the demangled string is null
904 terminated and return it. Otherwise, free the demangling decl. */
906 if (!success)
908 string_delete (declp);
910 else
912 string_appendn (declp, "", 1);
913 demangled = declp -> b;
915 return (demangled);
920 LOCAL FUNCTION
922 demangle_signature -- demangle the signature part of a mangled name
924 SYNOPSIS
926 static int
927 demangle_signature (struct work_stuff *work, const char **mangled,
928 string *declp);
930 DESCRIPTION
932 Consume and demangle the signature portion of the mangled name.
934 DECLP is the string where demangled output is being built. At
935 entry it contains the demangled root name from the mangled name
936 prefix. I.E. either a demangled operator name or the root function
937 name. In some special cases, it may contain nothing.
939 *MANGLED points to the current unconsumed location in the mangled
940 name. As tokens are consumed and demangling is performed, the
941 pointer is updated to continuously point at the next token to
942 be consumed.
944 Demangling GNU style mangled names is nasty because there is no
945 explicit token that marks the start of the outermost function
946 argument list. */
948 static int
949 demangle_signature (work, mangled, declp)
950 struct work_stuff *work;
951 const char **mangled;
952 string *declp;
954 int success = 1;
955 int func_done = 0;
956 int expect_func = 0;
957 int expect_return_type = 0;
958 const char *oldmangled = NULL;
959 string trawname;
960 string tname;
962 while (success && (**mangled != '\0'))
964 switch (**mangled)
966 case 'Q':
967 oldmangled = *mangled;
968 success = demangle_qualified (work, mangled, declp, 1, 0);
969 if (success)
970 remember_type (work, oldmangled, *mangled - oldmangled);
971 if (AUTO_DEMANGLING || GNU_DEMANGLING)
972 expect_func = 1;
973 oldmangled = NULL;
974 break;
976 case 'K':
977 oldmangled = *mangled;
978 success = demangle_qualified (work, mangled, declp, 1, 0);
979 if (AUTO_DEMANGLING || GNU_DEMANGLING)
981 expect_func = 1;
983 oldmangled = NULL;
984 break;
986 case 'S':
987 /* Static member function */
988 if (oldmangled == NULL)
990 oldmangled = *mangled;
992 (*mangled)++;
993 work -> static_type = 1;
994 break;
996 case 'C':
997 case 'V':
998 case 'u':
999 work->type_quals |= code_for_qualifier (**mangled);
1001 /* a qualified member function */
1002 if (oldmangled == NULL)
1003 oldmangled = *mangled;
1004 (*mangled)++;
1005 break;
1007 case 'L':
1008 /* Local class name follows after "Lnnn_" */
1009 if (HP_DEMANGLING)
1011 while (**mangled && (**mangled != '_'))
1012 (*mangled)++;
1013 if (!**mangled)
1014 success = 0;
1015 else
1016 (*mangled)++;
1018 else
1019 success = 0;
1020 break;
1022 case '0': case '1': case '2': case '3': case '4':
1023 case '5': case '6': case '7': case '8': case '9':
1024 if (oldmangled == NULL)
1026 oldmangled = *mangled;
1028 work->temp_start = -1; /* uppermost call to demangle_class */
1029 success = demangle_class (work, mangled, declp);
1030 if (success)
1032 remember_type (work, oldmangled, *mangled - oldmangled);
1034 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1036 /* EDG and others will have the "F", so we let the loop cycle
1037 if we are looking at one. */
1038 if (**mangled != 'F')
1039 expect_func = 1;
1041 oldmangled = NULL;
1042 break;
1044 case 'B':
1046 string s;
1047 success = do_type (work, mangled, &s);
1048 if (success)
1050 string_append (&s, SCOPE_STRING (work));
1051 string_prepends (declp, &s);
1053 oldmangled = NULL;
1054 expect_func = 1;
1056 break;
1058 case 'F':
1059 /* Function */
1060 /* ARM/HP style demangling includes a specific 'F' character after
1061 the class name. For GNU style, it is just implied. So we can
1062 safely just consume any 'F' at this point and be compatible
1063 with either style. */
1065 oldmangled = NULL;
1066 func_done = 1;
1067 (*mangled)++;
1069 /* For lucid/ARM/HP style we have to forget any types we might
1070 have remembered up to this point, since they were not argument
1071 types. GNU style considers all types seen as available for
1072 back references. See comment in demangle_args() */
1074 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1076 forget_types (work);
1078 success = demangle_args (work, mangled, declp);
1079 /* After picking off the function args, we expect to either
1080 find the function return type (preceded by an '_') or the
1081 end of the string. */
1082 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1084 ++(*mangled);
1085 /* At this level, we do not care about the return type. */
1086 success = do_type (work, mangled, &tname);
1087 string_delete (&tname);
1090 break;
1092 case 't':
1093 /* G++ Template */
1094 string_init(&trawname);
1095 string_init(&tname);
1096 if (oldmangled == NULL)
1098 oldmangled = *mangled;
1100 success = demangle_template (work, mangled, &tname,
1101 &trawname, 1, 1);
1102 if (success)
1104 remember_type (work, oldmangled, *mangled - oldmangled);
1106 string_append (&tname, SCOPE_STRING (work));
1108 string_prepends(declp, &tname);
1109 if (work -> destructor & 1)
1111 string_prepend (&trawname, "~");
1112 string_appends (declp, &trawname);
1113 work->destructor -= 1;
1115 if ((work->constructor & 1) || (work->destructor & 1))
1117 string_appends (declp, &trawname);
1118 work->constructor -= 1;
1120 string_delete(&trawname);
1121 string_delete(&tname);
1122 oldmangled = NULL;
1123 expect_func = 1;
1124 break;
1126 case '_':
1127 if (GNU_DEMANGLING && expect_return_type)
1129 /* Read the return type. */
1130 string return_type;
1131 string_init (&return_type);
1133 (*mangled)++;
1134 success = do_type (work, mangled, &return_type);
1135 APPEND_BLANK (&return_type);
1137 string_prepends (declp, &return_type);
1138 string_delete (&return_type);
1139 break;
1141 else
1142 /* At the outermost level, we cannot have a return type specified,
1143 so if we run into another '_' at this point we are dealing with
1144 a mangled name that is either bogus, or has been mangled by
1145 some algorithm we don't know how to deal with. So just
1146 reject the entire demangling. */
1147 /* However, "_nnn" is an expected suffix for alternate entry point
1148 numbered nnn for a function, with HP aCC, so skip over that
1149 without reporting failure. pai/1997-09-04 */
1150 if (HP_DEMANGLING)
1152 (*mangled)++;
1153 while (**mangled && isdigit ((unsigned char)**mangled))
1154 (*mangled)++;
1156 else
1157 success = 0;
1158 break;
1160 case 'H':
1161 if (GNU_DEMANGLING)
1163 /* A G++ template function. Read the template arguments. */
1164 success = demangle_template (work, mangled, declp, 0, 0,
1166 if (!(work->constructor & 1))
1167 expect_return_type = 1;
1168 (*mangled)++;
1169 break;
1171 else
1172 /* fall through */
1175 default:
1176 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1178 /* Assume we have stumbled onto the first outermost function
1179 argument token, and start processing args. */
1180 func_done = 1;
1181 success = demangle_args (work, mangled, declp);
1183 else
1185 /* Non-GNU demanglers use a specific token to mark the start
1186 of the outermost function argument tokens. Typically 'F',
1187 for ARM/HP-demangling, for example. So if we find something
1188 we are not prepared for, it must be an error. */
1189 success = 0;
1191 break;
1194 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1197 if (success && expect_func)
1199 func_done = 1;
1200 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1202 forget_types (work);
1204 success = demangle_args (work, mangled, declp);
1205 /* Since template include the mangling of their return types,
1206 we must set expect_func to 0 so that we don't try do
1207 demangle more arguments the next time we get here. */
1208 expect_func = 0;
1212 if (success && !func_done)
1214 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1216 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1217 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1218 first case, and need to ensure that the '(void)' gets added to
1219 the current declp. Note that with ARM/HP, the first case
1220 represents the name of a static data member 'foo::bar',
1221 which is in the current declp, so we leave it alone. */
1222 success = demangle_args (work, mangled, declp);
1225 if (success && PRINT_ARG_TYPES)
1227 if (work->static_type)
1228 string_append (declp, " static");
1229 if (work->type_quals != TYPE_UNQUALIFIED)
1231 APPEND_BLANK (declp);
1232 string_append (declp, qualifier_string (work->type_quals));
1236 return (success);
1239 #if 0
1241 static int
1242 demangle_method_args (work, mangled, declp)
1243 struct work_stuff *work;
1244 const char **mangled;
1245 string *declp;
1247 int success = 0;
1249 if (work -> static_type)
1251 string_append (declp, *mangled + 1);
1252 *mangled += strlen (*mangled);
1253 success = 1;
1255 else
1257 success = demangle_args (work, mangled, declp);
1259 return (success);
1262 #endif
1264 static int
1265 demangle_template_template_parm (work, mangled, tname)
1266 struct work_stuff *work;
1267 const char **mangled;
1268 string *tname;
1270 int i;
1271 int r;
1272 int need_comma = 0;
1273 int success = 1;
1274 string temp;
1276 string_append (tname, "template <");
1277 /* get size of template parameter list */
1278 if (get_count (mangled, &r))
1280 for (i = 0; i < r; i++)
1282 if (need_comma)
1284 string_append (tname, ", ");
1287 /* Z for type parameters */
1288 if (**mangled == 'Z')
1290 (*mangled)++;
1291 string_append (tname, "class");
1293 /* z for template parameters */
1294 else if (**mangled == 'z')
1296 (*mangled)++;
1297 success =
1298 demangle_template_template_parm (work, mangled, tname);
1299 if (!success)
1301 break;
1304 else
1306 /* temp is initialized in do_type */
1307 success = do_type (work, mangled, &temp);
1308 if (success)
1310 string_appends (tname, &temp);
1312 string_delete(&temp);
1313 if (!success)
1315 break;
1318 need_comma = 1;
1322 if (tname->p[-1] == '>')
1323 string_append (tname, " ");
1324 string_append (tname, "> class");
1325 return (success);
1328 static int
1329 demangle_integral_value (work, mangled, s)
1330 struct work_stuff *work;
1331 const char** mangled;
1332 string* s;
1334 int success;
1336 if (**mangled == 'E')
1338 int need_operator = 0;
1340 success = 1;
1341 string_appendn (s, "(", 1);
1342 (*mangled)++;
1343 while (success && **mangled != 'W' && **mangled != '\0')
1345 if (need_operator)
1347 size_t i;
1348 size_t len;
1350 success = 0;
1352 len = strlen (*mangled);
1354 for (i = 0;
1355 i < sizeof (optable) / sizeof (optable [0]);
1356 ++i)
1358 size_t l = strlen (optable[i].in);
1360 if (l <= len
1361 && memcmp (optable[i].in, *mangled, l) == 0)
1363 string_appendn (s, " ", 1);
1364 string_append (s, optable[i].out);
1365 string_appendn (s, " ", 1);
1366 success = 1;
1367 (*mangled) += l;
1368 break;
1372 if (!success)
1373 break;
1375 else
1376 need_operator = 1;
1378 success = demangle_template_value_parm (work, mangled, s,
1379 tk_integral);
1382 if (**mangled != 'W')
1383 success = 0;
1384 else
1386 string_appendn (s, ")", 1);
1387 (*mangled)++;
1390 else if (**mangled == 'Q' || **mangled == 'K')
1391 success = demangle_qualified (work, mangled, s, 0, 1);
1392 else
1394 success = 0;
1396 if (**mangled == 'm')
1398 string_appendn (s, "-", 1);
1399 (*mangled)++;
1401 while (isdigit ((unsigned char)**mangled))
1403 string_appendn (s, *mangled, 1);
1404 (*mangled)++;
1405 success = 1;
1409 return success;
1412 static int
1413 demangle_template_value_parm (work, mangled, s, tk)
1414 struct work_stuff *work;
1415 const char **mangled;
1416 string* s;
1417 type_kind_t tk;
1419 int success = 1;
1421 if (**mangled == 'Y')
1423 /* The next argument is a template parameter. */
1424 int idx;
1426 (*mangled)++;
1427 idx = consume_count_with_underscores (mangled);
1428 if (idx == -1
1429 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1430 || consume_count_with_underscores (mangled) == -1)
1431 return -1;
1432 if (work->tmpl_argvec)
1433 string_append (s, work->tmpl_argvec[idx]);
1434 else
1436 char buf[10];
1437 sprintf(buf, "T%d", idx);
1438 string_append (s, buf);
1441 else if (tk == tk_integral)
1442 success = demangle_integral_value (work, mangled, s);
1443 else if (tk == tk_char)
1445 char tmp[2];
1446 int val;
1447 if (**mangled == 'm')
1449 string_appendn (s, "-", 1);
1450 (*mangled)++;
1452 string_appendn (s, "'", 1);
1453 val = consume_count(mangled);
1454 if (val <= 0)
1455 success = 0;
1456 else
1458 tmp[0] = (char)val;
1459 tmp[1] = '\0';
1460 string_appendn (s, &tmp[0], 1);
1461 string_appendn (s, "'", 1);
1464 else if (tk == tk_bool)
1466 int val = consume_count (mangled);
1467 if (val == 0)
1468 string_appendn (s, "false", 5);
1469 else if (val == 1)
1470 string_appendn (s, "true", 4);
1471 else
1472 success = 0;
1474 else if (tk == tk_real)
1476 if (**mangled == 'm')
1478 string_appendn (s, "-", 1);
1479 (*mangled)++;
1481 while (isdigit ((unsigned char)**mangled))
1483 string_appendn (s, *mangled, 1);
1484 (*mangled)++;
1486 if (**mangled == '.') /* fraction */
1488 string_appendn (s, ".", 1);
1489 (*mangled)++;
1490 while (isdigit ((unsigned char)**mangled))
1492 string_appendn (s, *mangled, 1);
1493 (*mangled)++;
1496 if (**mangled == 'e') /* exponent */
1498 string_appendn (s, "e", 1);
1499 (*mangled)++;
1500 while (isdigit ((unsigned char)**mangled))
1502 string_appendn (s, *mangled, 1);
1503 (*mangled)++;
1507 else if (tk == tk_pointer || tk == tk_reference)
1509 int symbol_len = consume_count (mangled);
1510 if (symbol_len == -1)
1511 return -1;
1512 if (symbol_len == 0)
1513 string_appendn (s, "0", 1);
1514 else
1516 char *p = xmalloc (symbol_len + 1), *q;
1517 strncpy (p, *mangled, symbol_len);
1518 p [symbol_len] = '\0';
1519 /* We use cplus_demangle here, rather than
1520 internal_cplus_demangle, because the name of the entity
1521 mangled here does not make use of any of the squangling
1522 or type-code information we have built up thus far; it is
1523 mangled independently. */
1524 q = cplus_demangle (p, work->options);
1525 if (tk == tk_pointer)
1526 string_appendn (s, "&", 1);
1527 /* FIXME: Pointer-to-member constants should get a
1528 qualifying class name here. */
1529 if (q)
1531 string_append (s, q);
1532 free (q);
1534 else
1535 string_append (s, p);
1536 free (p);
1538 *mangled += symbol_len;
1541 return success;
1544 /* Demangle the template name in MANGLED. The full name of the
1545 template (e.g., S<int>) is placed in TNAME. The name without the
1546 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1547 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1548 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1549 the tmeplate is remembered in the list of back-referenceable
1550 types. */
1552 static int
1553 demangle_template (work, mangled, tname, trawname, is_type, remember)
1554 struct work_stuff *work;
1555 const char **mangled;
1556 string *tname;
1557 string *trawname;
1558 int is_type;
1559 int remember;
1561 int i;
1562 int r;
1563 int need_comma = 0;
1564 int success = 0;
1565 const char *start;
1566 int is_java_array = 0;
1567 string temp;
1568 int bindex = 0;
1570 (*mangled)++;
1571 if (is_type)
1573 if (remember)
1574 bindex = register_Btype (work);
1575 start = *mangled;
1576 /* get template name */
1577 if (**mangled == 'z')
1579 int idx;
1580 (*mangled)++;
1581 (*mangled)++;
1583 idx = consume_count_with_underscores (mangled);
1584 if (idx == -1
1585 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1586 || consume_count_with_underscores (mangled) == -1)
1587 return (0);
1589 if (work->tmpl_argvec)
1591 string_append (tname, work->tmpl_argvec[idx]);
1592 if (trawname)
1593 string_append (trawname, work->tmpl_argvec[idx]);
1595 else
1597 char buf[10];
1598 sprintf(buf, "T%d", idx);
1599 string_append (tname, buf);
1600 if (trawname)
1601 string_append (trawname, buf);
1604 else
1606 if ((r = consume_count (mangled)) <= 0
1607 || (int) strlen (*mangled) < r)
1609 return (0);
1611 is_java_array = (work -> options & DMGL_JAVA)
1612 && strncmp (*mangled, "JArray1Z", 8) == 0;
1613 if (! is_java_array)
1615 string_appendn (tname, *mangled, r);
1617 if (trawname)
1618 string_appendn (trawname, *mangled, r);
1619 *mangled += r;
1622 if (!is_java_array)
1623 string_append (tname, "<");
1624 /* get size of template parameter list */
1625 if (!get_count (mangled, &r))
1627 return (0);
1629 if (!is_type)
1631 /* Create an array for saving the template argument values. */
1632 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1633 work->ntmpl_args = r;
1634 for (i = 0; i < r; i++)
1635 work->tmpl_argvec[i] = 0;
1637 for (i = 0; i < r; i++)
1639 if (need_comma)
1641 string_append (tname, ", ");
1643 /* Z for type parameters */
1644 if (**mangled == 'Z')
1646 (*mangled)++;
1647 /* temp is initialized in do_type */
1648 success = do_type (work, mangled, &temp);
1649 if (success)
1651 string_appends (tname, &temp);
1653 if (!is_type)
1655 /* Save the template argument. */
1656 int len = temp.p - temp.b;
1657 work->tmpl_argvec[i] = xmalloc (len + 1);
1658 memcpy (work->tmpl_argvec[i], temp.b, len);
1659 work->tmpl_argvec[i][len] = '\0';
1662 string_delete(&temp);
1663 if (!success)
1665 break;
1668 /* z for template parameters */
1669 else if (**mangled == 'z')
1671 int r2;
1672 (*mangled)++;
1673 success = demangle_template_template_parm (work, mangled, tname);
1675 if (success
1676 && (r2 = consume_count (mangled)) > 0
1677 && (int) strlen (*mangled) >= r2)
1679 string_append (tname, " ");
1680 string_appendn (tname, *mangled, r2);
1681 if (!is_type)
1683 /* Save the template argument. */
1684 int len = r2;
1685 work->tmpl_argvec[i] = xmalloc (len + 1);
1686 memcpy (work->tmpl_argvec[i], *mangled, len);
1687 work->tmpl_argvec[i][len] = '\0';
1689 *mangled += r2;
1691 if (!success)
1693 break;
1696 else
1698 string param;
1699 string* s;
1701 /* otherwise, value parameter */
1703 /* temp is initialized in do_type */
1704 success = do_type (work, mangled, &temp);
1705 string_delete(&temp);
1706 if (!success)
1707 break;
1709 if (!is_type)
1711 s = &param;
1712 string_init (s);
1714 else
1715 s = tname;
1717 success = demangle_template_value_parm (work, mangled, s,
1718 (type_kind_t) success);
1720 if (!success)
1722 if (!is_type)
1723 string_delete (s);
1724 success = 0;
1725 break;
1728 if (!is_type)
1730 int len = s->p - s->b;
1731 work->tmpl_argvec[i] = xmalloc (len + 1);
1732 memcpy (work->tmpl_argvec[i], s->b, len);
1733 work->tmpl_argvec[i][len] = '\0';
1735 string_appends (tname, s);
1736 string_delete (s);
1739 need_comma = 1;
1741 if (is_java_array)
1743 string_append (tname, "[]");
1745 else
1747 if (tname->p[-1] == '>')
1748 string_append (tname, " ");
1749 string_append (tname, ">");
1752 if (is_type && remember)
1753 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1756 if (work -> static_type)
1758 string_append (declp, *mangled + 1);
1759 *mangled += strlen (*mangled);
1760 success = 1;
1762 else
1764 success = demangle_args (work, mangled, declp);
1768 return (success);
1771 static int
1772 arm_pt (work, mangled, n, anchor, args)
1773 struct work_stuff *work;
1774 const char *mangled;
1775 int n;
1776 const char **anchor, **args;
1778 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1779 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1780 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1782 int len;
1783 *args = *anchor + 6;
1784 len = consume_count (args);
1785 if (len == -1)
1786 return 0;
1787 if (*args + len == mangled + n && **args == '_')
1789 ++*args;
1790 return 1;
1793 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1795 if ((*anchor = mystrstr (mangled, "__tm__"))
1796 || (*anchor = mystrstr (mangled, "__ps__"))
1797 || (*anchor = mystrstr (mangled, "__pt__")))
1799 int len;
1800 *args = *anchor + 6;
1801 len = consume_count (args);
1802 if (len == -1)
1803 return 0;
1804 if (*args + len == mangled + n && **args == '_')
1806 ++*args;
1807 return 1;
1810 else if ((*anchor = mystrstr (mangled, "__S")))
1812 int len;
1813 *args = *anchor + 3;
1814 len = consume_count (args);
1815 if (len == -1)
1816 return 0;
1817 if (*args + len == mangled + n && **args == '_')
1819 ++*args;
1820 return 1;
1825 return 0;
1828 static void
1829 demangle_arm_hp_template (work, mangled, n, declp)
1830 struct work_stuff *work;
1831 const char **mangled;
1832 int n;
1833 string *declp;
1835 const char *p;
1836 const char *args;
1837 const char *e = *mangled + n;
1838 string arg;
1840 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1841 template args */
1842 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1844 char *start_spec_args = NULL;
1846 /* First check for and omit template specialization pseudo-arguments,
1847 such as in "Spec<#1,#1.*>" */
1848 start_spec_args = strchr (*mangled, '<');
1849 if (start_spec_args && (start_spec_args - *mangled < n))
1850 string_appendn (declp, *mangled, start_spec_args - *mangled);
1851 else
1852 string_appendn (declp, *mangled, n);
1853 (*mangled) += n + 1;
1854 string_init (&arg);
1855 if (work->temp_start == -1) /* non-recursive call */
1856 work->temp_start = declp->p - declp->b;
1857 string_append (declp, "<");
1858 while (1)
1860 string_clear (&arg);
1861 switch (**mangled)
1863 case 'T':
1864 /* 'T' signals a type parameter */
1865 (*mangled)++;
1866 if (!do_type (work, mangled, &arg))
1867 goto hpacc_template_args_done;
1868 break;
1870 case 'U':
1871 case 'S':
1872 /* 'U' or 'S' signals an integral value */
1873 if (!do_hpacc_template_const_value (work, mangled, &arg))
1874 goto hpacc_template_args_done;
1875 break;
1877 case 'A':
1878 /* 'A' signals a named constant expression (literal) */
1879 if (!do_hpacc_template_literal (work, mangled, &arg))
1880 goto hpacc_template_args_done;
1881 break;
1883 default:
1884 /* Today, 1997-09-03, we have only the above types
1885 of template parameters */
1886 /* FIXME: maybe this should fail and return null */
1887 goto hpacc_template_args_done;
1889 string_appends (declp, &arg);
1890 /* Check if we're at the end of template args.
1891 0 if at end of static member of template class,
1892 _ if done with template args for a function */
1893 if ((**mangled == '\000') || (**mangled == '_'))
1894 break;
1895 else
1896 string_append (declp, ",");
1898 hpacc_template_args_done:
1899 string_append (declp, ">");
1900 string_delete (&arg);
1901 if (**mangled == '_')
1902 (*mangled)++;
1903 return;
1905 /* ARM template? (Also handles HP cfront extensions) */
1906 else if (arm_pt (work, *mangled, n, &p, &args))
1908 string type_str;
1910 string_init (&arg);
1911 string_appendn (declp, *mangled, p - *mangled);
1912 if (work->temp_start == -1) /* non-recursive call */
1913 work->temp_start = declp->p - declp->b;
1914 string_append (declp, "<");
1915 /* should do error checking here */
1916 while (args < e) {
1917 string_clear (&arg);
1919 /* Check for type or literal here */
1920 switch (*args)
1922 /* HP cfront extensions to ARM for template args */
1923 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1924 /* FIXME: We handle only numeric literals for HP cfront */
1925 case 'X':
1926 /* A typed constant value follows */
1927 args++;
1928 if (!do_type (work, &args, &type_str))
1929 goto cfront_template_args_done;
1930 string_append (&arg, "(");
1931 string_appends (&arg, &type_str);
1932 string_append (&arg, ")");
1933 if (*args != 'L')
1934 goto cfront_template_args_done;
1935 args++;
1936 /* Now snarf a literal value following 'L' */
1937 if (!snarf_numeric_literal (&args, &arg))
1938 goto cfront_template_args_done;
1939 break;
1941 case 'L':
1942 /* Snarf a literal following 'L' */
1943 args++;
1944 if (!snarf_numeric_literal (&args, &arg))
1945 goto cfront_template_args_done;
1946 break;
1947 default:
1948 /* Not handling other HP cfront stuff */
1949 if (!do_type (work, &args, &arg))
1950 goto cfront_template_args_done;
1952 string_appends (declp, &arg);
1953 string_append (declp, ",");
1955 cfront_template_args_done:
1956 string_delete (&arg);
1957 if (args >= e)
1958 --declp->p; /* remove extra comma */
1959 string_append (declp, ">");
1961 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1962 && (*mangled)[9] == 'N'
1963 && (*mangled)[8] == (*mangled)[10]
1964 && strchr (cplus_markers, (*mangled)[8]))
1966 /* A member of the anonymous namespace. */
1967 string_append (declp, "{anonymous}");
1969 else
1971 if (work->temp_start == -1) /* non-recursive call only */
1972 work->temp_start = 0; /* disable in recursive calls */
1973 string_appendn (declp, *mangled, n);
1975 *mangled += n;
1978 /* Extract a class name, possibly a template with arguments, from the
1979 mangled string; qualifiers, local class indicators, etc. have
1980 already been dealt with */
1982 static int
1983 demangle_class_name (work, mangled, declp)
1984 struct work_stuff *work;
1985 const char **mangled;
1986 string *declp;
1988 int n;
1989 int success = 0;
1991 n = consume_count (mangled);
1992 if (n == -1)
1993 return 0;
1994 if ((int) strlen (*mangled) >= n)
1996 demangle_arm_hp_template (work, mangled, n, declp);
1997 success = 1;
2000 return (success);
2005 LOCAL FUNCTION
2007 demangle_class -- demangle a mangled class sequence
2009 SYNOPSIS
2011 static int
2012 demangle_class (struct work_stuff *work, const char **mangled,
2013 strint *declp)
2015 DESCRIPTION
2017 DECLP points to the buffer into which demangling is being done.
2019 *MANGLED points to the current token to be demangled. On input,
2020 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2021 On exit, it points to the next token after the mangled class on
2022 success, or the first unconsumed token on failure.
2024 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2025 we are demangling a constructor or destructor. In this case
2026 we prepend "class::class" or "class::~class" to DECLP.
2028 Otherwise, we prepend "class::" to the current DECLP.
2030 Reset the constructor/destructor flags once they have been
2031 "consumed". This allows demangle_class to be called later during
2032 the same demangling, to do normal class demangling.
2034 Returns 1 if demangling is successful, 0 otherwise.
2038 static int
2039 demangle_class (work, mangled, declp)
2040 struct work_stuff *work;
2041 const char **mangled;
2042 string *declp;
2044 int success = 0;
2045 int btype;
2046 string class_name;
2047 char *save_class_name_end = 0;
2049 string_init (&class_name);
2050 btype = register_Btype (work);
2051 if (demangle_class_name (work, mangled, &class_name))
2053 save_class_name_end = class_name.p;
2054 if ((work->constructor & 1) || (work->destructor & 1))
2056 /* adjust so we don't include template args */
2057 if (work->temp_start && (work->temp_start != -1))
2059 class_name.p = class_name.b + work->temp_start;
2061 string_prepends (declp, &class_name);
2062 if (work -> destructor & 1)
2064 string_prepend (declp, "~");
2065 work -> destructor -= 1;
2067 else
2069 work -> constructor -= 1;
2072 class_name.p = save_class_name_end;
2073 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2074 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2075 string_prepend (declp, SCOPE_STRING (work));
2076 string_prepends (declp, &class_name);
2077 success = 1;
2079 string_delete (&class_name);
2080 return (success);
2085 LOCAL FUNCTION
2087 demangle_prefix -- consume the mangled name prefix and find signature
2089 SYNOPSIS
2091 static int
2092 demangle_prefix (struct work_stuff *work, const char **mangled,
2093 string *declp);
2095 DESCRIPTION
2097 Consume and demangle the prefix of the mangled name.
2099 DECLP points to the string buffer into which demangled output is
2100 placed. On entry, the buffer is empty. On exit it contains
2101 the root function name, the demangled operator name, or in some
2102 special cases either nothing or the completely demangled result.
2104 MANGLED points to the current pointer into the mangled name. As each
2105 token of the mangled name is consumed, it is updated. Upon entry
2106 the current mangled name pointer points to the first character of
2107 the mangled name. Upon exit, it should point to the first character
2108 of the signature if demangling was successful, or to the first
2109 unconsumed character if demangling of the prefix was unsuccessful.
2111 Returns 1 on success, 0 otherwise.
2114 static int
2115 demangle_prefix (work, mangled, declp)
2116 struct work_stuff *work;
2117 const char **mangled;
2118 string *declp;
2120 int success = 1;
2121 const char *scan;
2122 int i;
2124 if (strlen(*mangled) > 6
2125 && (strncmp(*mangled, "_imp__", 6) == 0
2126 || strncmp(*mangled, "__imp_", 6) == 0))
2128 /* it's a symbol imported from a PE dynamic library. Check for both
2129 new style prefix _imp__ and legacy __imp_ used by older versions
2130 of dlltool. */
2131 (*mangled) += 6;
2132 work->dllimported = 1;
2134 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2136 char *marker = strchr (cplus_markers, (*mangled)[8]);
2137 if (marker != NULL && *marker == (*mangled)[10])
2139 if ((*mangled)[9] == 'D')
2141 /* it's a GNU global destructor to be executed at program exit */
2142 (*mangled) += 11;
2143 work->destructor = 2;
2144 if (gnu_special (work, mangled, declp))
2145 return success;
2147 else if ((*mangled)[9] == 'I')
2149 /* it's a GNU global constructor to be executed at program init */
2150 (*mangled) += 11;
2151 work->constructor = 2;
2152 if (gnu_special (work, mangled, declp))
2153 return success;
2157 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2159 /* it's a ARM global destructor to be executed at program exit */
2160 (*mangled) += 7;
2161 work->destructor = 2;
2163 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2165 /* it's a ARM global constructor to be executed at program initial */
2166 (*mangled) += 7;
2167 work->constructor = 2;
2170 /* This block of code is a reduction in strength time optimization
2172 scan = mystrstr (*mangled, "__"); */
2175 scan = *mangled;
2177 do {
2178 scan = strchr (scan, '_');
2179 } while (scan != NULL && *++scan != '_');
2181 if (scan != NULL) --scan;
2184 if (scan != NULL)
2186 /* We found a sequence of two or more '_', ensure that we start at
2187 the last pair in the sequence. */
2188 i = strspn (scan, "_");
2189 if (i > 2)
2191 scan += (i - 2);
2195 if (scan == NULL)
2197 success = 0;
2199 else if (work -> static_type)
2201 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2203 success = 0;
2206 else if ((scan == *mangled)
2207 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2208 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2210 /* The ARM says nothing about the mangling of local variables.
2211 But cfront mangles local variables by prepending __<nesting_level>
2212 to them. As an extension to ARM demangling we handle this case. */
2213 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2214 && isdigit ((unsigned char)scan[2]))
2216 *mangled = scan + 2;
2217 consume_count (mangled);
2218 string_append (declp, *mangled);
2219 *mangled += strlen (*mangled);
2220 success = 1;
2222 else
2224 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2225 names like __Q2_3foo3bar for nested type names. So don't accept
2226 this style of constructor for cfront demangling. A GNU
2227 style member-template constructor starts with 'H'. */
2228 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2229 work -> constructor += 1;
2230 *mangled = scan + 2;
2233 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2235 /* Cfront-style parameterized type. Handled later as a signature. */
2236 success = 1;
2238 /* ARM template? */
2239 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2241 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2242 || (scan[2] == 'p' && scan[3] == 's')
2243 || (scan[2] == 'p' && scan[3] == 't')))
2245 /* EDG-style parameterized type. Handled later as a signature. */
2246 success = 1;
2248 /* EDG template? */
2249 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2251 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2252 && (scan[2] != 't'))
2254 /* Mangled name starts with "__". Skip over any leading '_' characters,
2255 then find the next "__" that separates the prefix from the signature.
2257 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2258 || (arm_special (mangled, declp) == 0))
2260 while (*scan == '_')
2262 scan++;
2264 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2266 /* No separator (I.E. "__not_mangled"), or empty signature
2267 (I.E. "__not_mangled_either__") */
2268 success = 0;
2270 else
2272 const char *tmp;
2274 /* Look for the LAST occurrence of __, allowing names to
2275 have the '__' sequence embedded in them. */
2276 if (!(ARM_DEMANGLING || HP_DEMANGLING))
2278 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
2279 scan = tmp;
2281 if (*(scan + 2) == '\0')
2282 success = 0;
2283 else
2284 demangle_function_name (work, mangled, declp, scan);
2288 else if (*(scan + 2) != '\0')
2290 /* Mangled name does not start with "__" but does have one somewhere
2291 in there with non empty stuff after it. Looks like a global
2292 function name. */
2293 demangle_function_name (work, mangled, declp, scan);
2295 else
2297 /* Doesn't look like a mangled name */
2298 success = 0;
2301 if (!success && (work->constructor == 2 || work->destructor == 2))
2303 string_append (declp, *mangled);
2304 *mangled += strlen (*mangled);
2305 success = 1;
2307 return (success);
2312 LOCAL FUNCTION
2314 gnu_special -- special handling of gnu mangled strings
2316 SYNOPSIS
2318 static int
2319 gnu_special (struct work_stuff *work, const char **mangled,
2320 string *declp);
2323 DESCRIPTION
2325 Process some special GNU style mangling forms that don't fit
2326 the normal pattern. For example:
2328 _$_3foo (destructor for class foo)
2329 _vt$foo (foo virtual table)
2330 _vt$foo$bar (foo::bar virtual table)
2331 __vt_foo (foo virtual table, new style with thunks)
2332 _3foo$varname (static data member)
2333 _Q22rs2tu$vw (static data member)
2334 __t6vector1Zii (constructor with template)
2335 __thunk_4__$_7ostream (virtual function thunk)
2338 static int
2339 gnu_special (work, mangled, declp)
2340 struct work_stuff *work;
2341 const char **mangled;
2342 string *declp;
2344 int n;
2345 int success = 1;
2346 const char *p;
2348 if ((*mangled)[0] == '_'
2349 && strchr (cplus_markers, (*mangled)[1]) != NULL
2350 && (*mangled)[2] == '_')
2352 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2353 (*mangled) += 3;
2354 work -> destructor += 1;
2356 else if ((*mangled)[0] == '_'
2357 && (((*mangled)[1] == '_'
2358 && (*mangled)[2] == 'v'
2359 && (*mangled)[3] == 't'
2360 && (*mangled)[4] == '_')
2361 || ((*mangled)[1] == 'v'
2362 && (*mangled)[2] == 't'
2363 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2365 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2366 and create the decl. Note that we consume the entire mangled
2367 input string, which means that demangle_signature has no work
2368 to do. */
2369 if ((*mangled)[2] == 'v')
2370 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2371 else
2372 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2373 while (**mangled != '\0')
2375 switch (**mangled)
2377 case 'Q':
2378 case 'K':
2379 success = demangle_qualified (work, mangled, declp, 0, 1);
2380 break;
2381 case 't':
2382 success = demangle_template (work, mangled, declp, 0, 1,
2384 break;
2385 default:
2386 if (isdigit((unsigned char)*mangled[0]))
2388 n = consume_count(mangled);
2389 /* We may be seeing a too-large size, or else a
2390 ".<digits>" indicating a static local symbol. In
2391 any case, declare victory and move on; *don't* try
2392 to use n to allocate. */
2393 if (n > (int) strlen (*mangled))
2395 success = 1;
2396 break;
2399 else
2401 n = strcspn (*mangled, cplus_markers);
2403 string_appendn (declp, *mangled, n);
2404 (*mangled) += n;
2407 p = strpbrk (*mangled, cplus_markers);
2408 if (success && ((p == NULL) || (p == *mangled)))
2410 if (p != NULL)
2412 string_append (declp, SCOPE_STRING (work));
2413 (*mangled)++;
2416 else
2418 success = 0;
2419 break;
2422 if (success)
2423 string_append (declp, " virtual table");
2425 else if ((*mangled)[0] == '_'
2426 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2427 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2429 /* static data member, "_3foo$varname" for example */
2430 (*mangled)++;
2431 switch (**mangled)
2433 case 'Q':
2434 case 'K':
2435 success = demangle_qualified (work, mangled, declp, 0, 1);
2436 break;
2437 case 't':
2438 success = demangle_template (work, mangled, declp, 0, 1, 1);
2439 break;
2440 default:
2441 n = consume_count (mangled);
2442 if (n < 0 || n > strlen (*mangled))
2444 success = 0;
2445 break;
2447 string_appendn (declp, *mangled, n);
2448 (*mangled) += n;
2450 if (success && (p == *mangled))
2452 /* Consumed everything up to the cplus_marker, append the
2453 variable name. */
2454 (*mangled)++;
2455 string_append (declp, SCOPE_STRING (work));
2456 n = strlen (*mangled);
2457 string_appendn (declp, *mangled, n);
2458 (*mangled) += n;
2460 else
2462 success = 0;
2465 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2467 int delta;
2469 (*mangled) += 8;
2470 delta = consume_count (mangled);
2471 if (delta == -1)
2472 success = 0;
2473 else
2475 char *method = internal_cplus_demangle (work, ++*mangled);
2477 if (method)
2479 char buf[50];
2480 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2481 string_append (declp, buf);
2482 string_append (declp, method);
2483 free (method);
2484 n = strlen (*mangled);
2485 (*mangled) += n;
2487 else
2489 success = 0;
2493 else if (strncmp (*mangled, "__t", 3) == 0
2494 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2496 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2497 (*mangled) += 4;
2498 switch (**mangled)
2500 case 'Q':
2501 case 'K':
2502 success = demangle_qualified (work, mangled, declp, 0, 1);
2503 break;
2504 case 't':
2505 success = demangle_template (work, mangled, declp, 0, 1, 1);
2506 break;
2507 default:
2508 success = demangle_fund_type (work, mangled, declp);
2509 break;
2511 if (success && **mangled != '\0')
2512 success = 0;
2513 if (success)
2514 string_append (declp, p);
2516 else
2518 success = 0;
2520 return (success);
2523 static void
2524 recursively_demangle(work, mangled, result, namelength)
2525 struct work_stuff *work;
2526 const char **mangled;
2527 string *result;
2528 int namelength;
2530 char * recurse = (char *)NULL;
2531 char * recurse_dem = (char *)NULL;
2533 recurse = (char *) xmalloc (namelength + 1);
2534 memcpy (recurse, *mangled, namelength);
2535 recurse[namelength] = '\000';
2537 recurse_dem = cplus_demangle (recurse, work->options);
2539 if (recurse_dem)
2541 string_append (result, recurse_dem);
2542 free (recurse_dem);
2544 else
2546 string_appendn (result, *mangled, namelength);
2548 free (recurse);
2549 *mangled += namelength;
2554 LOCAL FUNCTION
2556 arm_special -- special handling of ARM/lucid mangled strings
2558 SYNOPSIS
2560 static int
2561 arm_special (const char **mangled,
2562 string *declp);
2565 DESCRIPTION
2567 Process some special ARM style mangling forms that don't fit
2568 the normal pattern. For example:
2570 __vtbl__3foo (foo virtual table)
2571 __vtbl__3foo__3bar (bar::foo virtual table)
2575 static int
2576 arm_special (mangled, declp)
2577 const char **mangled;
2578 string *declp;
2580 int n;
2581 int success = 1;
2582 const char *scan;
2584 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2586 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2587 and create the decl. Note that we consume the entire mangled
2588 input string, which means that demangle_signature has no work
2589 to do. */
2590 scan = *mangled + ARM_VTABLE_STRLEN;
2591 while (*scan != '\0') /* first check it can be demangled */
2593 n = consume_count (&scan);
2594 if (n == -1)
2596 return (0); /* no good */
2598 scan += n;
2599 if (scan[0] == '_' && scan[1] == '_')
2601 scan += 2;
2604 (*mangled) += ARM_VTABLE_STRLEN;
2605 while (**mangled != '\0')
2607 n = consume_count (mangled);
2608 if (n == -1
2609 || n > strlen (*mangled))
2610 return 0;
2611 string_prependn (declp, *mangled, n);
2612 (*mangled) += n;
2613 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2615 string_prepend (declp, "::");
2616 (*mangled) += 2;
2619 string_append (declp, " virtual table");
2621 else
2623 success = 0;
2625 return (success);
2630 LOCAL FUNCTION
2632 demangle_qualified -- demangle 'Q' qualified name strings
2634 SYNOPSIS
2636 static int
2637 demangle_qualified (struct work_stuff *, const char *mangled,
2638 string *result, int isfuncname, int append);
2640 DESCRIPTION
2642 Demangle a qualified name, such as "Q25Outer5Inner" which is
2643 the mangled form of "Outer::Inner". The demangled output is
2644 prepended or appended to the result string according to the
2645 state of the append flag.
2647 If isfuncname is nonzero, then the qualified name we are building
2648 is going to be used as a member function name, so if it is a
2649 constructor or destructor function, append an appropriate
2650 constructor or destructor name. I.E. for the above example,
2651 the result for use as a constructor is "Outer::Inner::Inner"
2652 and the result for use as a destructor is "Outer::Inner::~Inner".
2654 BUGS
2656 Numeric conversion is ASCII dependent (FIXME).
2660 static int
2661 demangle_qualified (work, mangled, result, isfuncname, append)
2662 struct work_stuff *work;
2663 const char **mangled;
2664 string *result;
2665 int isfuncname;
2666 int append;
2668 int qualifiers = 0;
2669 int success = 1;
2670 const char *p;
2671 char num[2];
2672 string temp;
2673 string last_name;
2674 int bindex = register_Btype (work);
2676 /* We only make use of ISFUNCNAME if the entity is a constructor or
2677 destructor. */
2678 isfuncname = (isfuncname
2679 && ((work->constructor & 1) || (work->destructor & 1)));
2681 string_init (&temp);
2682 string_init (&last_name);
2684 if ((*mangled)[0] == 'K')
2686 /* Squangling qualified name reuse */
2687 int idx;
2688 (*mangled)++;
2689 idx = consume_count_with_underscores (mangled);
2690 if (idx == -1 || idx >= work -> numk)
2691 success = 0;
2692 else
2693 string_append (&temp, work -> ktypevec[idx]);
2695 else
2696 switch ((*mangled)[1])
2698 case '_':
2699 /* GNU mangled name with more than 9 classes. The count is preceded
2700 by an underscore (to distinguish it from the <= 9 case) and followed
2701 by an underscore. */
2702 p = *mangled + 2;
2703 qualifiers = atoi (p);
2704 if (!isdigit ((unsigned char)*p) || *p == '0')
2705 success = 0;
2707 /* Skip the digits. */
2708 while (isdigit ((unsigned char)*p))
2709 ++p;
2711 if (*p != '_')
2712 success = 0;
2714 *mangled = p + 1;
2715 break;
2717 case '1':
2718 case '2':
2719 case '3':
2720 case '4':
2721 case '5':
2722 case '6':
2723 case '7':
2724 case '8':
2725 case '9':
2726 /* The count is in a single digit. */
2727 num[0] = (*mangled)[1];
2728 num[1] = '\0';
2729 qualifiers = atoi (num);
2731 /* If there is an underscore after the digit, skip it. This is
2732 said to be for ARM-qualified names, but the ARM makes no
2733 mention of such an underscore. Perhaps cfront uses one. */
2734 if ((*mangled)[2] == '_')
2736 (*mangled)++;
2738 (*mangled) += 2;
2739 break;
2741 case '0':
2742 default:
2743 success = 0;
2746 if (!success)
2747 return success;
2749 /* Pick off the names and collect them in the temp buffer in the order
2750 in which they are found, separated by '::'. */
2752 while (qualifiers-- > 0)
2754 int remember_K = 1;
2755 string_clear (&last_name);
2757 if (*mangled[0] == '_')
2758 (*mangled)++;
2760 if (*mangled[0] == 't')
2762 /* Here we always append to TEMP since we will want to use
2763 the template name without the template parameters as a
2764 constructor or destructor name. The appropriate
2765 (parameter-less) value is returned by demangle_template
2766 in LAST_NAME. We do not remember the template type here,
2767 in order to match the G++ mangling algorithm. */
2768 success = demangle_template(work, mangled, &temp,
2769 &last_name, 1, 0);
2770 if (!success)
2771 break;
2773 else if (*mangled[0] == 'K')
2775 int idx;
2776 (*mangled)++;
2777 idx = consume_count_with_underscores (mangled);
2778 if (idx == -1 || idx >= work->numk)
2779 success = 0;
2780 else
2781 string_append (&temp, work->ktypevec[idx]);
2782 remember_K = 0;
2784 if (!success) break;
2786 else
2788 if (EDG_DEMANGLING)
2790 int namelength;
2791 /* Now recursively demangle the qualifier
2792 * This is necessary to deal with templates in
2793 * mangling styles like EDG */
2794 namelength = consume_count (mangled);
2795 if (namelength == -1)
2797 success = 0;
2798 break;
2800 recursively_demangle(work, mangled, &temp, namelength);
2802 else
2804 success = do_type (work, mangled, &last_name);
2805 if (!success)
2806 break;
2807 string_appends (&temp, &last_name);
2811 if (remember_K)
2812 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2814 if (qualifiers > 0)
2815 string_append (&temp, SCOPE_STRING (work));
2818 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2820 /* If we are using the result as a function name, we need to append
2821 the appropriate '::' separated constructor or destructor name.
2822 We do this here because this is the most convenient place, where
2823 we already have a pointer to the name and the length of the name. */
2825 if (isfuncname)
2827 string_append (&temp, SCOPE_STRING (work));
2828 if (work -> destructor & 1)
2829 string_append (&temp, "~");
2830 string_appends (&temp, &last_name);
2833 /* Now either prepend the temp buffer to the result, or append it,
2834 depending upon the state of the append flag. */
2836 if (append)
2837 string_appends (result, &temp);
2838 else
2840 if (!STRING_EMPTY (result))
2841 string_append (&temp, SCOPE_STRING (work));
2842 string_prepends (result, &temp);
2845 string_delete (&last_name);
2846 string_delete (&temp);
2847 return (success);
2852 LOCAL FUNCTION
2854 get_count -- convert an ascii count to integer, consuming tokens
2856 SYNOPSIS
2858 static int
2859 get_count (const char **type, int *count)
2861 DESCRIPTION
2863 Assume that *type points at a count in a mangled name; set
2864 *count to its value, and set *type to the next character after
2865 the count. There are some weird rules in effect here.
2867 If *type does not point at a string of digits, return zero.
2869 If *type points at a string of digits followed by an
2870 underscore, set *count to their value as an integer, advance
2871 *type to point *after the underscore, and return 1.
2873 If *type points at a string of digits not followed by an
2874 underscore, consume only the first digit. Set *count to its
2875 value as an integer, leave *type pointing after that digit,
2876 and return 1.
2878 The excuse for this odd behavior: in the ARM and HP demangling
2879 styles, a type can be followed by a repeat count of the form
2880 `Nxy', where:
2882 `x' is a single digit specifying how many additional copies
2883 of the type to append to the argument list, and
2885 `y' is one or more digits, specifying the zero-based index of
2886 the first repeated argument in the list. Yes, as you're
2887 unmangling the name you can figure this out yourself, but
2888 it's there anyway.
2890 So, for example, in `bar__3fooFPiN51', the first argument is a
2891 pointer to an integer (`Pi'), and then the next five arguments
2892 are the same (`N5'), and the first repeat is the function's
2893 second argument (`1').
2896 static int
2897 get_count (type, count)
2898 const char **type;
2899 int *count;
2901 const char *p;
2902 int n;
2904 if (!isdigit ((unsigned char)**type))
2906 return (0);
2908 else
2910 *count = **type - '0';
2911 (*type)++;
2912 if (isdigit ((unsigned char)**type))
2914 p = *type;
2915 n = *count;
2918 n *= 10;
2919 n += *p - '0';
2920 p++;
2922 while (isdigit ((unsigned char)*p));
2923 if (*p == '_')
2925 *type = p + 1;
2926 *count = n;
2930 return (1);
2933 /* RESULT will be initialised here; it will be freed on failure. The
2934 value returned is really a type_kind_t. */
2936 static int
2937 do_type (work, mangled, result)
2938 struct work_stuff *work;
2939 const char **mangled;
2940 string *result;
2942 int n;
2943 int done;
2944 int success;
2945 string decl;
2946 const char *remembered_type;
2947 int type_quals;
2948 string btype;
2949 type_kind_t tk = tk_none;
2951 string_init (&btype);
2952 string_init (&decl);
2953 string_init (result);
2955 done = 0;
2956 success = 1;
2957 while (success && !done)
2959 int member;
2960 switch (**mangled)
2963 /* A pointer type */
2964 case 'P':
2965 case 'p':
2966 (*mangled)++;
2967 if (! (work -> options & DMGL_JAVA))
2968 string_prepend (&decl, "*");
2969 if (tk == tk_none)
2970 tk = tk_pointer;
2971 break;
2973 /* A reference type */
2974 case 'R':
2975 (*mangled)++;
2976 string_prepend (&decl, "&");
2977 if (tk == tk_none)
2978 tk = tk_reference;
2979 break;
2981 /* An array */
2982 case 'A':
2984 ++(*mangled);
2985 if (!STRING_EMPTY (&decl)
2986 && (decl.b[0] == '*' || decl.b[0] == '&'))
2988 string_prepend (&decl, "(");
2989 string_append (&decl, ")");
2991 string_append (&decl, "[");
2992 if (**mangled != '_')
2993 success = demangle_template_value_parm (work, mangled, &decl,
2994 tk_integral);
2995 if (**mangled == '_')
2996 ++(*mangled);
2997 string_append (&decl, "]");
2998 break;
3001 /* A back reference to a previously seen type */
3002 case 'T':
3003 (*mangled)++;
3004 if (!get_count (mangled, &n) || n >= work -> ntypes)
3006 success = 0;
3008 else
3010 remembered_type = work -> typevec[n];
3011 mangled = &remembered_type;
3013 break;
3015 /* A function */
3016 case 'F':
3017 (*mangled)++;
3018 if (!STRING_EMPTY (&decl)
3019 && (decl.b[0] == '*' || decl.b[0] == '&'))
3021 string_prepend (&decl, "(");
3022 string_append (&decl, ")");
3024 /* After picking off the function args, we expect to either find the
3025 function return type (preceded by an '_') or the end of the
3026 string. */
3027 if (!demangle_nested_args (work, mangled, &decl)
3028 || (**mangled != '_' && **mangled != '\0'))
3030 success = 0;
3031 break;
3033 if (success && (**mangled == '_'))
3034 (*mangled)++;
3035 break;
3037 case 'M':
3038 case 'O':
3040 type_quals = TYPE_UNQUALIFIED;
3042 member = **mangled == 'M';
3043 (*mangled)++;
3044 if (!isdigit ((unsigned char)**mangled) && **mangled != 't')
3046 success = 0;
3047 break;
3050 string_append (&decl, ")");
3051 string_prepend (&decl, SCOPE_STRING (work));
3052 if (isdigit ((unsigned char)**mangled))
3054 n = consume_count (mangled);
3055 if (n == -1
3056 || (int) strlen (*mangled) < n)
3058 success = 0;
3059 break;
3061 string_prependn (&decl, *mangled, n);
3062 *mangled += n;
3064 else
3066 string temp;
3067 string_init (&temp);
3068 success = demangle_template (work, mangled, &temp,
3069 NULL, 1, 1);
3070 if (success)
3072 string_prependn (&decl, temp.b, temp.p - temp.b);
3073 string_clear (&temp);
3075 else
3076 break;
3078 string_prepend (&decl, "(");
3079 if (member)
3081 switch (**mangled)
3083 case 'C':
3084 case 'V':
3085 case 'u':
3086 type_quals |= code_for_qualifier (**mangled);
3087 (*mangled)++;
3088 break;
3090 default:
3091 break;
3094 if (*(*mangled)++ != 'F')
3096 success = 0;
3097 break;
3100 if ((member && !demangle_nested_args (work, mangled, &decl))
3101 || **mangled != '_')
3103 success = 0;
3104 break;
3106 (*mangled)++;
3107 if (! PRINT_ANSI_QUALIFIERS)
3109 break;
3111 if (type_quals != TYPE_UNQUALIFIED)
3113 APPEND_BLANK (&decl);
3114 string_append (&decl, qualifier_string (type_quals));
3116 break;
3118 case 'G':
3119 (*mangled)++;
3120 break;
3122 case 'C':
3123 case 'V':
3124 case 'u':
3125 if (PRINT_ANSI_QUALIFIERS)
3127 if (!STRING_EMPTY (&decl))
3128 string_prepend (&decl, " ");
3130 string_prepend (&decl, demangle_qualifier (**mangled));
3132 (*mangled)++;
3133 break;
3138 /* fall through */
3139 default:
3140 done = 1;
3141 break;
3145 if (success) switch (**mangled)
3147 /* A qualified name, such as "Outer::Inner". */
3148 case 'Q':
3149 case 'K':
3151 success = demangle_qualified (work, mangled, result, 0, 1);
3152 break;
3155 /* A back reference to a previously seen squangled type */
3156 case 'B':
3157 (*mangled)++;
3158 if (!get_count (mangled, &n) || n >= work -> numb)
3159 success = 0;
3160 else
3161 string_append (result, work->btypevec[n]);
3162 break;
3164 case 'X':
3165 case 'Y':
3166 /* A template parm. We substitute the corresponding argument. */
3168 int idx;
3170 (*mangled)++;
3171 idx = consume_count_with_underscores (mangled);
3173 if (idx == -1
3174 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3175 || consume_count_with_underscores (mangled) == -1)
3177 success = 0;
3178 break;
3181 if (work->tmpl_argvec)
3182 string_append (result, work->tmpl_argvec[idx]);
3183 else
3185 char buf[10];
3186 sprintf(buf, "T%d", idx);
3187 string_append (result, buf);
3190 success = 1;
3192 break;
3194 default:
3195 success = demangle_fund_type (work, mangled, result);
3196 if (tk == tk_none)
3197 tk = (type_kind_t) success;
3198 break;
3201 if (success)
3203 if (!STRING_EMPTY (&decl))
3205 string_append (result, " ");
3206 string_appends (result, &decl);
3209 else
3210 string_delete (result);
3211 string_delete (&decl);
3213 if (success)
3214 /* Assume an integral type, if we're not sure. */
3215 return (int) ((tk == tk_none) ? tk_integral : tk);
3216 else
3217 return 0;
3220 /* Given a pointer to a type string that represents a fundamental type
3221 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3222 string in which the demangled output is being built in RESULT, and
3223 the WORK structure, decode the types and add them to the result.
3225 For example:
3227 "Ci" => "const int"
3228 "Sl" => "signed long"
3229 "CUs" => "const unsigned short"
3231 The value returned is really a type_kind_t. */
3233 static int
3234 demangle_fund_type (work, mangled, result)
3235 struct work_stuff *work;
3236 const char **mangled;
3237 string *result;
3239 int done = 0;
3240 int success = 1;
3241 char buf[10];
3242 int dec = 0;
3243 string btype;
3244 type_kind_t tk = tk_integral;
3246 string_init (&btype);
3248 /* First pick off any type qualifiers. There can be more than one. */
3250 while (!done)
3252 switch (**mangled)
3254 case 'C':
3255 case 'V':
3256 case 'u':
3257 if (PRINT_ANSI_QUALIFIERS)
3259 if (!STRING_EMPTY (result))
3260 string_prepend (result, " ");
3261 string_prepend (result, demangle_qualifier (**mangled));
3263 (*mangled)++;
3264 break;
3265 case 'U':
3266 (*mangled)++;
3267 APPEND_BLANK (result);
3268 string_append (result, "unsigned");
3269 break;
3270 case 'S': /* signed char only */
3271 (*mangled)++;
3272 APPEND_BLANK (result);
3273 string_append (result, "signed");
3274 break;
3275 case 'J':
3276 (*mangled)++;
3277 APPEND_BLANK (result);
3278 string_append (result, "__complex");
3279 break;
3280 default:
3281 done = 1;
3282 break;
3286 /* Now pick off the fundamental type. There can be only one. */
3288 switch (**mangled)
3290 case '\0':
3291 case '_':
3292 break;
3293 case 'v':
3294 (*mangled)++;
3295 APPEND_BLANK (result);
3296 string_append (result, "void");
3297 break;
3298 case 'x':
3299 (*mangled)++;
3300 APPEND_BLANK (result);
3301 string_append (result, "long long");
3302 break;
3303 case 'l':
3304 (*mangled)++;
3305 APPEND_BLANK (result);
3306 string_append (result, "long");
3307 break;
3308 case 'i':
3309 (*mangled)++;
3310 APPEND_BLANK (result);
3311 string_append (result, "int");
3312 break;
3313 case 's':
3314 (*mangled)++;
3315 APPEND_BLANK (result);
3316 string_append (result, "short");
3317 break;
3318 case 'b':
3319 (*mangled)++;
3320 APPEND_BLANK (result);
3321 string_append (result, "bool");
3322 tk = tk_bool;
3323 break;
3324 case 'c':
3325 (*mangled)++;
3326 APPEND_BLANK (result);
3327 string_append (result, "char");
3328 tk = tk_char;
3329 break;
3330 case 'w':
3331 (*mangled)++;
3332 APPEND_BLANK (result);
3333 string_append (result, "wchar_t");
3334 tk = tk_char;
3335 break;
3336 case 'r':
3337 (*mangled)++;
3338 APPEND_BLANK (result);
3339 string_append (result, "long double");
3340 tk = tk_real;
3341 break;
3342 case 'd':
3343 (*mangled)++;
3344 APPEND_BLANK (result);
3345 string_append (result, "double");
3346 tk = tk_real;
3347 break;
3348 case 'f':
3349 (*mangled)++;
3350 APPEND_BLANK (result);
3351 string_append (result, "float");
3352 tk = tk_real;
3353 break;
3354 case 'G':
3355 (*mangled)++;
3356 if (!isdigit ((unsigned char)**mangled))
3358 success = 0;
3359 break;
3361 case 'I':
3362 ++(*mangled);
3363 if (**mangled == '_')
3365 int i;
3366 ++(*mangled);
3367 for (i = 0;
3368 (i < sizeof (buf) - 1 && **mangled && **mangled != '_');
3369 ++(*mangled), ++i)
3370 buf[i] = **mangled;
3371 if (**mangled != '_')
3373 success = 0;
3374 break;
3376 buf[i] = '\0';
3377 ++(*mangled);
3379 else
3381 strncpy (buf, *mangled, 2);
3382 buf[2] = '\0';
3383 *mangled += 2;
3385 sscanf (buf, "%x", &dec);
3386 sprintf (buf, "int%i_t", dec);
3387 APPEND_BLANK (result);
3388 string_append (result, buf);
3389 break;
3391 /* fall through */
3392 /* An explicit type, such as "6mytype" or "7integer" */
3393 case '0':
3394 case '1':
3395 case '2':
3396 case '3':
3397 case '4':
3398 case '5':
3399 case '6':
3400 case '7':
3401 case '8':
3402 case '9':
3404 int bindex = register_Btype (work);
3405 string btype;
3406 string_init (&btype);
3407 if (demangle_class_name (work, mangled, &btype)) {
3408 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3409 APPEND_BLANK (result);
3410 string_appends (result, &btype);
3412 else
3413 success = 0;
3414 string_delete (&btype);
3415 break;
3417 case 't':
3419 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3420 string_appends (result, &btype);
3421 break;
3423 default:
3424 success = 0;
3425 break;
3428 return success ? ((int) tk) : 0;
3432 /* Handle a template's value parameter for HP aCC (extension from ARM)
3433 **mangled points to 'S' or 'U' */
3435 static int
3436 do_hpacc_template_const_value (work, mangled, result)
3437 struct work_stuff *work;
3438 const char **mangled;
3439 string *result;
3441 int unsigned_const;
3443 if (**mangled != 'U' && **mangled != 'S')
3444 return 0;
3446 unsigned_const = (**mangled == 'U');
3448 (*mangled)++;
3450 switch (**mangled)
3452 case 'N':
3453 string_append (result, "-");
3454 /* fall through */
3455 case 'P':
3456 (*mangled)++;
3457 break;
3458 case 'M':
3459 /* special case for -2^31 */
3460 string_append (result, "-2147483648");
3461 (*mangled)++;
3462 return 1;
3463 default:
3464 return 0;
3467 /* We have to be looking at an integer now */
3468 if (!(isdigit ((unsigned char)**mangled)))
3469 return 0;
3471 /* We only deal with integral values for template
3472 parameters -- so it's OK to look only for digits */
3473 while (isdigit ((unsigned char)**mangled))
3475 char_str[0] = **mangled;
3476 string_append (result, char_str);
3477 (*mangled)++;
3480 if (unsigned_const)
3481 string_append (result, "U");
3483 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3484 with L or LL suffixes. pai/1997-09-03 */
3486 return 1; /* success */
3489 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3490 **mangled is pointing to the 'A' */
3492 static int
3493 do_hpacc_template_literal (work, mangled, result)
3494 struct work_stuff *work;
3495 const char **mangled;
3496 string *result;
3498 int literal_len = 0;
3499 char * recurse;
3500 char * recurse_dem;
3502 if (**mangled != 'A')
3503 return 0;
3505 (*mangled)++;
3507 literal_len = consume_count (mangled);
3509 if (literal_len <= 0)
3510 return 0;
3512 /* Literal parameters are names of arrays, functions, etc. and the
3513 canonical representation uses the address operator */
3514 string_append (result, "&");
3516 /* Now recursively demangle the literal name */
3517 recurse = (char *) xmalloc (literal_len + 1);
3518 memcpy (recurse, *mangled, literal_len);
3519 recurse[literal_len] = '\000';
3521 recurse_dem = cplus_demangle (recurse, work->options);
3523 if (recurse_dem)
3525 string_append (result, recurse_dem);
3526 free (recurse_dem);
3528 else
3530 string_appendn (result, *mangled, literal_len);
3532 (*mangled) += literal_len;
3533 free (recurse);
3535 return 1;
3538 static int
3539 snarf_numeric_literal (args, arg)
3540 const char ** args;
3541 string * arg;
3543 if (**args == '-')
3545 char_str[0] = '-';
3546 string_append (arg, char_str);
3547 (*args)++;
3549 else if (**args == '+')
3550 (*args)++;
3552 if (!isdigit ((unsigned char)**args))
3553 return 0;
3555 while (isdigit ((unsigned char)**args))
3557 char_str[0] = **args;
3558 string_append (arg, char_str);
3559 (*args)++;
3562 return 1;
3565 /* Demangle the next argument, given by MANGLED into RESULT, which
3566 *should be an uninitialized* string. It will be initialized here,
3567 and free'd should anything go wrong. */
3569 static int
3570 do_arg (work, mangled, result)
3571 struct work_stuff *work;
3572 const char **mangled;
3573 string *result;
3575 /* Remember where we started so that we can record the type, for
3576 non-squangling type remembering. */
3577 const char *start = *mangled;
3579 string_init (result);
3581 if (work->nrepeats > 0)
3583 --work->nrepeats;
3585 if (work->previous_argument == 0)
3586 return 0;
3588 /* We want to reissue the previous type in this argument list. */
3589 string_appends (result, work->previous_argument);
3590 return 1;
3593 if (**mangled == 'n')
3595 /* A squangling-style repeat. */
3596 (*mangled)++;
3597 work->nrepeats = consume_count(mangled);
3599 if (work->nrepeats <= 0)
3600 /* This was not a repeat count after all. */
3601 return 0;
3603 if (work->nrepeats > 9)
3605 if (**mangled != '_')
3606 /* The repeat count should be followed by an '_' in this
3607 case. */
3608 return 0;
3609 else
3610 (*mangled)++;
3613 /* Now, the repeat is all set up. */
3614 return do_arg (work, mangled, result);
3617 /* Save the result in WORK->previous_argument so that we can find it
3618 if it's repeated. Note that saving START is not good enough: we
3619 do not want to add additional types to the back-referenceable
3620 type vector when processing a repeated type. */
3621 if (work->previous_argument)
3622 string_clear (work->previous_argument);
3623 else
3625 work->previous_argument = (string*) xmalloc (sizeof (string));
3626 string_init (work->previous_argument);
3629 if (!do_type (work, mangled, work->previous_argument))
3630 return 0;
3632 string_appends (result, work->previous_argument);
3634 remember_type (work, start, *mangled - start);
3635 return 1;
3638 static void
3639 remember_type (work, start, len)
3640 struct work_stuff *work;
3641 const char *start;
3642 int len;
3644 char *tem;
3646 if (work->forgetting_types)
3647 return;
3649 if (work -> ntypes >= work -> typevec_size)
3651 if (work -> typevec_size == 0)
3653 work -> typevec_size = 3;
3654 work -> typevec
3655 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3657 else
3659 work -> typevec_size *= 2;
3660 work -> typevec
3661 = (char **) xrealloc ((char *)work -> typevec,
3662 sizeof (char *) * work -> typevec_size);
3665 tem = xmalloc (len + 1);
3666 memcpy (tem, start, len);
3667 tem[len] = '\0';
3668 work -> typevec[work -> ntypes++] = tem;
3672 /* Remember a K type class qualifier. */
3673 static void
3674 remember_Ktype (work, start, len)
3675 struct work_stuff *work;
3676 const char *start;
3677 int len;
3679 char *tem;
3681 if (work -> numk >= work -> ksize)
3683 if (work -> ksize == 0)
3685 work -> ksize = 5;
3686 work -> ktypevec
3687 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3689 else
3691 work -> ksize *= 2;
3692 work -> ktypevec
3693 = (char **) xrealloc ((char *)work -> ktypevec,
3694 sizeof (char *) * work -> ksize);
3697 tem = xmalloc (len + 1);
3698 memcpy (tem, start, len);
3699 tem[len] = '\0';
3700 work -> ktypevec[work -> numk++] = tem;
3703 /* Register a B code, and get an index for it. B codes are registered
3704 as they are seen, rather than as they are completed, so map<temp<char> >
3705 registers map<temp<char> > as B0, and temp<char> as B1 */
3707 static int
3708 register_Btype (work)
3709 struct work_stuff *work;
3711 int ret;
3713 if (work -> numb >= work -> bsize)
3715 if (work -> bsize == 0)
3717 work -> bsize = 5;
3718 work -> btypevec
3719 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3721 else
3723 work -> bsize *= 2;
3724 work -> btypevec
3725 = (char **) xrealloc ((char *)work -> btypevec,
3726 sizeof (char *) * work -> bsize);
3729 ret = work -> numb++;
3730 work -> btypevec[ret] = NULL;
3731 return(ret);
3734 /* Store a value into a previously registered B code type. */
3736 static void
3737 remember_Btype (work, start, len, index)
3738 struct work_stuff *work;
3739 const char *start;
3740 int len, index;
3742 char *tem;
3744 tem = xmalloc (len + 1);
3745 memcpy (tem, start, len);
3746 tem[len] = '\0';
3747 work -> btypevec[index] = tem;
3750 /* Lose all the info related to B and K type codes. */
3751 static void
3752 forget_B_and_K_types (work)
3753 struct work_stuff *work;
3755 int i;
3757 while (work -> numk > 0)
3759 i = --(work -> numk);
3760 if (work -> ktypevec[i] != NULL)
3762 free (work -> ktypevec[i]);
3763 work -> ktypevec[i] = NULL;
3767 while (work -> numb > 0)
3769 i = --(work -> numb);
3770 if (work -> btypevec[i] != NULL)
3772 free (work -> btypevec[i]);
3773 work -> btypevec[i] = NULL;
3777 /* Forget the remembered types, but not the type vector itself. */
3779 static void
3780 forget_types (work)
3781 struct work_stuff *work;
3783 int i;
3785 while (work -> ntypes > 0)
3787 i = --(work -> ntypes);
3788 if (work -> typevec[i] != NULL)
3790 free (work -> typevec[i]);
3791 work -> typevec[i] = NULL;
3796 /* Process the argument list part of the signature, after any class spec
3797 has been consumed, as well as the first 'F' character (if any). For
3798 example:
3800 "__als__3fooRT0" => process "RT0"
3801 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3803 DECLP must be already initialised, usually non-empty. It won't be freed
3804 on failure.
3806 Note that g++ differs significantly from ARM and lucid style mangling
3807 with regards to references to previously seen types. For example, given
3808 the source fragment:
3810 class foo {
3811 public:
3812 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3815 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3816 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3818 g++ produces the names:
3820 __3fooiRT0iT2iT2
3821 foo__FiR3fooiT1iT1
3823 while lcc (and presumably other ARM style compilers as well) produces:
3825 foo__FiR3fooT1T2T1T2
3826 __ct__3fooFiR3fooT1T2T1T2
3828 Note that g++ bases its type numbers starting at zero and counts all
3829 previously seen types, while lucid/ARM bases its type numbers starting
3830 at one and only considers types after it has seen the 'F' character
3831 indicating the start of the function args. For lucid/ARM style, we
3832 account for this difference by discarding any previously seen types when
3833 we see the 'F' character, and subtracting one from the type number
3834 reference.
3838 static int
3839 demangle_args (work, mangled, declp)
3840 struct work_stuff *work;
3841 const char **mangled;
3842 string *declp;
3844 string arg;
3845 int need_comma = 0;
3846 int r;
3847 int t;
3848 const char *tem;
3849 char temptype;
3851 if (PRINT_ARG_TYPES)
3853 string_append (declp, "(");
3854 if (**mangled == '\0')
3856 string_append (declp, "void");
3860 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3861 || work->nrepeats > 0)
3863 if ((**mangled == 'N') || (**mangled == 'T'))
3865 temptype = *(*mangled)++;
3867 if (temptype == 'N')
3869 if (!get_count (mangled, &r))
3871 return (0);
3874 else
3876 r = 1;
3878 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3880 /* If we have 10 or more types we might have more than a 1 digit
3881 index so we'll have to consume the whole count here. This
3882 will lose if the next thing is a type name preceded by a
3883 count but it's impossible to demangle that case properly
3884 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3885 Pc, ...)" or "(..., type12, char *, ...)" */
3886 if ((t = consume_count(mangled)) <= 0)
3888 return (0);
3891 else
3893 if (!get_count (mangled, &t))
3895 return (0);
3898 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3900 t--;
3902 /* Validate the type index. Protect against illegal indices from
3903 malformed type strings. */
3904 if ((t < 0) || (t >= work -> ntypes))
3906 return (0);
3908 while (work->nrepeats > 0 || --r >= 0)
3910 tem = work -> typevec[t];
3911 if (need_comma && PRINT_ARG_TYPES)
3913 string_append (declp, ", ");
3915 if (!do_arg (work, &tem, &arg))
3917 return (0);
3919 if (PRINT_ARG_TYPES)
3921 string_appends (declp, &arg);
3923 string_delete (&arg);
3924 need_comma = 1;
3927 else
3929 if (need_comma && PRINT_ARG_TYPES)
3930 string_append (declp, ", ");
3931 if (!do_arg (work, mangled, &arg))
3932 return (0);
3933 if (PRINT_ARG_TYPES)
3934 string_appends (declp, &arg);
3935 string_delete (&arg);
3936 need_comma = 1;
3940 if (**mangled == 'e')
3942 (*mangled)++;
3943 if (PRINT_ARG_TYPES)
3945 if (need_comma)
3947 string_append (declp, ",");
3949 string_append (declp, "...");
3953 if (PRINT_ARG_TYPES)
3955 string_append (declp, ")");
3957 return (1);
3960 /* Like demangle_args, but for demangling the argument lists of function
3961 and method pointers or references, not top-level declarations. */
3963 static int
3964 demangle_nested_args (work, mangled, declp)
3965 struct work_stuff *work;
3966 const char **mangled;
3967 string *declp;
3969 string* saved_previous_argument;
3970 int result;
3971 int saved_nrepeats;
3973 /* The G++ name-mangling algorithm does not remember types on nested
3974 argument lists, unless -fsquangling is used, and in that case the
3975 type vector updated by remember_type is not used. So, we turn
3976 off remembering of types here. */
3977 ++work->forgetting_types;
3979 /* For the repeat codes used with -fsquangling, we must keep track of
3980 the last argument. */
3981 saved_previous_argument = work->previous_argument;
3982 saved_nrepeats = work->nrepeats;
3983 work->previous_argument = 0;
3984 work->nrepeats = 0;
3986 /* Actually demangle the arguments. */
3987 result = demangle_args (work, mangled, declp);
3989 /* Restore the previous_argument field. */
3990 if (work->previous_argument)
3991 string_delete (work->previous_argument);
3992 work->previous_argument = saved_previous_argument;
3993 --work->forgetting_types;
3994 work->nrepeats = saved_nrepeats;
3996 return result;
3999 static void
4000 demangle_function_name (work, mangled, declp, scan)
4001 struct work_stuff *work;
4002 const char **mangled;
4003 string *declp;
4004 const char *scan;
4006 size_t i;
4007 string type;
4008 const char *tem;
4010 string_appendn (declp, (*mangled), scan - (*mangled));
4011 string_need (declp, 1);
4012 *(declp -> p) = '\0';
4014 /* Consume the function name, including the "__" separating the name
4015 from the signature. We are guaranteed that SCAN points to the
4016 separator. */
4018 (*mangled) = scan + 2;
4019 /* We may be looking at an instantiation of a template function:
4020 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4021 following _F marks the start of the function arguments. Handle
4022 the template arguments first. */
4024 if (HP_DEMANGLING && (**mangled == 'X'))
4026 demangle_arm_hp_template (work, mangled, 0, declp);
4027 /* This leaves MANGLED pointing to the 'F' marking func args */
4030 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4033 /* See if we have an ARM style constructor or destructor operator.
4034 If so, then just record it, clear the decl, and return.
4035 We can't build the actual constructor/destructor decl until later,
4036 when we recover the class name from the signature. */
4038 if (strcmp (declp -> b, "__ct") == 0)
4040 work -> constructor += 1;
4041 string_clear (declp);
4042 return;
4044 else if (strcmp (declp -> b, "__dt") == 0)
4046 work -> destructor += 1;
4047 string_clear (declp);
4048 return;
4052 if (declp->p - declp->b >= 3
4053 && declp->b[0] == 'o'
4054 && declp->b[1] == 'p'
4055 && strchr (cplus_markers, declp->b[2]) != NULL)
4057 /* see if it's an assignment expression */
4058 if (declp->p - declp->b >= 10 /* op$assign_ */
4059 && memcmp (declp->b + 3, "assign_", 7) == 0)
4061 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4063 int len = declp->p - declp->b - 10;
4064 if ((int) strlen (optable[i].in) == len
4065 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4067 string_clear (declp);
4068 string_append (declp, "operator");
4069 string_append (declp, optable[i].out);
4070 string_append (declp, "=");
4071 break;
4075 else
4077 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4079 int len = declp->p - declp->b - 3;
4080 if ((int) strlen (optable[i].in) == len
4081 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4083 string_clear (declp);
4084 string_append (declp, "operator");
4085 string_append (declp, optable[i].out);
4086 break;
4091 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4092 && strchr (cplus_markers, declp->b[4]) != NULL)
4094 /* type conversion operator */
4095 tem = declp->b + 5;
4096 if (do_type (work, &tem, &type))
4098 string_clear (declp);
4099 string_append (declp, "operator ");
4100 string_appends (declp, &type);
4101 string_delete (&type);
4104 else if (declp->b[0] == '_' && declp->b[1] == '_'
4105 && declp->b[2] == 'o' && declp->b[3] == 'p')
4107 /* ANSI. */
4108 /* type conversion operator. */
4109 tem = declp->b + 4;
4110 if (do_type (work, &tem, &type))
4112 string_clear (declp);
4113 string_append (declp, "operator ");
4114 string_appends (declp, &type);
4115 string_delete (&type);
4118 else if (declp->b[0] == '_' && declp->b[1] == '_'
4119 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4120 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4122 if (declp->b[4] == '\0')
4124 /* Operator. */
4125 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4127 if (strlen (optable[i].in) == 2
4128 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4130 string_clear (declp);
4131 string_append (declp, "operator");
4132 string_append (declp, optable[i].out);
4133 break;
4137 else
4139 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4141 /* Assignment. */
4142 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4144 if (strlen (optable[i].in) == 3
4145 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4147 string_clear (declp);
4148 string_append (declp, "operator");
4149 string_append (declp, optable[i].out);
4150 break;
4158 /* a mini string-handling package */
4160 static void
4161 string_need (s, n)
4162 string *s;
4163 int n;
4165 int tem;
4167 if (s->b == NULL)
4169 if (n < 32)
4171 n = 32;
4173 s->p = s->b = xmalloc (n);
4174 s->e = s->b + n;
4176 else if (s->e - s->p < n)
4178 tem = s->p - s->b;
4179 n += tem;
4180 n *= 2;
4181 s->b = xrealloc (s->b, n);
4182 s->p = s->b + tem;
4183 s->e = s->b + n;
4187 static void
4188 string_delete (s)
4189 string *s;
4191 if (s->b != NULL)
4193 free (s->b);
4194 s->b = s->e = s->p = NULL;
4198 static void
4199 string_init (s)
4200 string *s;
4202 s->b = s->p = s->e = NULL;
4205 static void
4206 string_clear (s)
4207 string *s;
4209 s->p = s->b;
4212 #if 0
4214 static int
4215 string_empty (s)
4216 string *s;
4218 return (s->b == s->p);
4221 #endif
4223 static void
4224 string_append (p, s)
4225 string *p;
4226 const char *s;
4228 int n;
4229 if (s == NULL || *s == '\0')
4230 return;
4231 n = strlen (s);
4232 string_need (p, n);
4233 memcpy (p->p, s, n);
4234 p->p += n;
4237 static void
4238 string_appends (p, s)
4239 string *p, *s;
4241 int n;
4243 if (s->b != s->p)
4245 n = s->p - s->b;
4246 string_need (p, n);
4247 memcpy (p->p, s->b, n);
4248 p->p += n;
4252 static void
4253 string_appendn (p, s, n)
4254 string *p;
4255 const char *s;
4256 int n;
4258 if (n != 0)
4260 string_need (p, n);
4261 memcpy (p->p, s, n);
4262 p->p += n;
4266 static void
4267 string_prepend (p, s)
4268 string *p;
4269 const char *s;
4271 if (s != NULL && *s != '\0')
4273 string_prependn (p, s, strlen (s));
4277 static void
4278 string_prepends (p, s)
4279 string *p, *s;
4281 if (s->b != s->p)
4283 string_prependn (p, s->b, s->p - s->b);
4287 static void
4288 string_prependn (p, s, n)
4289 string *p;
4290 const char *s;
4291 int n;
4293 char *q;
4295 if (n != 0)
4297 string_need (p, n);
4298 for (q = p->p - 1; q >= p->b; q--)
4300 q[n] = q[0];
4302 memcpy (p->b, s, n);
4303 p->p += n;
4307 /* To generate a standalone demangler program for testing purposes,
4308 just compile and link this file with -DMAIN and libiberty.a. When
4309 run, it demangles each command line arg, or each stdin string, and
4310 prints the result on stdout. */
4312 #ifdef MAIN
4314 #include "getopt.h"
4316 static char *program_name;
4317 static char *program_version = VERSION;
4318 static int flags = DMGL_PARAMS | DMGL_ANSI;
4320 static void demangle_it PARAMS ((char *));
4321 static void usage PARAMS ((FILE *, int));
4322 static void fatal PARAMS ((char *));
4324 static void
4325 demangle_it (mangled_name)
4326 char *mangled_name;
4328 char *result;
4330 result = cplus_demangle (mangled_name, flags);
4331 if (result == NULL)
4333 printf ("%s\n", mangled_name);
4335 else
4337 printf ("%s\n", result);
4338 free (result);
4342 static void
4343 usage (stream, status)
4344 FILE *stream;
4345 int status;
4347 fprintf (stream, "\
4348 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4349 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4350 [--help] [--version] [arg...]\n",
4351 program_name);
4352 exit (status);
4355 #define MBUF_SIZE 32767
4356 char mbuffer[MBUF_SIZE];
4358 /* Defined in the automatically-generated underscore.c. */
4359 extern int prepends_underscore;
4361 int strip_underscore = 0;
4363 static struct option long_options[] = {
4364 {"strip-underscores", no_argument, 0, '_'},
4365 {"format", required_argument, 0, 's'},
4366 {"help", no_argument, 0, 'h'},
4367 {"java", no_argument, 0, 'j'},
4368 {"no-strip-underscores", no_argument, 0, 'n'},
4369 {"version", no_argument, 0, 'v'},
4370 {0, no_argument, 0, 0}
4373 /* More 'friendly' abort that prints the line and file.
4374 config.h can #define abort fancy_abort if you like that sort of thing. */
4376 void
4377 fancy_abort ()
4379 fatal ("Internal gcc abort.");
4383 /* Fill in TABLE so that TABLE[C] is true iff C (as an unsigned char)
4384 is a valid symbol component, in the standard assembler symbol
4385 syntax. */
4386 void
4387 standard_symbol_alphabet (char *table)
4389 int c;
4391 for (c = 0; c < 256; c++)
4392 table[c] = isalnum(c);
4394 table['_'] = 1;
4395 table['$'] = 1;
4396 table['.'] = 1;
4400 /* Fill in TABLE so that TABLE[C] is true iff C (as an unsigned char)
4401 is a valid symbol name component in an HP object file.
4403 Note that, since HP's compiler generates object code straight from
4404 C++ source, without going through an assembler, its mangled
4405 identifiers can use all sorts of characters that no assembler would
4406 tolerate, so the alphabet this function creates is a little odd.
4407 Here are some sample mangled identifiers offered by HP:
4409 typeid*__XT24AddressIndExpClassMember_
4410 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4411 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4413 This still seems really weird to me, since nowhere else in this
4414 file is there anything to recognize curly brackets, parens, etc.
4415 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4416 this is right, but I still strongly suspect that there's a
4417 misunderstanding here.
4419 If we decide it's better for c++filt to use HP's assembler syntax
4420 to scrape identifiers out of its input, here's the definition of
4421 the symbol name syntax from the HP assembler manual:
4423 Symbols are composed of uppercase and lowercase letters, decimal
4424 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4425 underscore (_). A symbol can begin with a letter, digit underscore or
4426 dollar sign. If a symbol begins with a digit, it must contain a
4427 non-digit character.
4429 So have fun. */
4430 void
4431 hp_symbol_alphabet (char *table)
4433 char *c;
4435 standard_symbol_alphabet (table);
4437 for (c = "<>#,*&[]:(){}"; *c; c++)
4438 table[(unsigned char) *c] = 1;
4443 main (argc, argv)
4444 int argc;
4445 char **argv;
4447 char *result;
4448 int c;
4449 char symbol_alphabet[256];
4451 program_name = argv[0];
4453 strip_underscore = prepends_underscore;
4455 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4457 switch (c)
4459 case '?':
4460 usage (stderr, 1);
4461 break;
4462 case 'h':
4463 usage (stdout, 0);
4464 case 'n':
4465 strip_underscore = 0;
4466 break;
4467 case 'v':
4468 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4469 exit (0);
4470 case '_':
4471 strip_underscore = 1;
4472 break;
4473 case 'j':
4474 flags |= DMGL_JAVA;
4475 break;
4476 case 's':
4477 if (strcmp (optarg, "gnu") == 0)
4479 current_demangling_style = gnu_demangling;
4481 else if (strcmp (optarg, "lucid") == 0)
4483 current_demangling_style = lucid_demangling;
4485 else if (strcmp (optarg, "arm") == 0)
4487 current_demangling_style = arm_demangling;
4489 else if (strcmp (optarg, "hp") == 0)
4491 current_demangling_style = hp_demangling;
4493 else if (strcmp (optarg, "edg") == 0)
4495 current_demangling_style = edg_demangling;
4497 else
4499 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4500 program_name, optarg);
4501 exit (1);
4503 break;
4507 if (optind < argc)
4509 for ( ; optind < argc; optind++)
4511 demangle_it (argv[optind]);
4514 else
4516 switch (current_demangling_style)
4518 case gnu_demangling:
4519 case lucid_demangling:
4520 case arm_demangling:
4521 case edg_demangling:
4522 standard_symbol_alphabet (symbol_alphabet);
4523 break;
4524 case hp_demangling:
4525 hp_symbol_alphabet (symbol_alphabet);
4526 break;
4527 default:
4528 /* Folks should explicitly indicate the appropriate alphabet for
4529 each demangling. Providing a default would allow the
4530 question to go unconsidered. */
4531 abort ();
4534 for (;;)
4536 int i = 0;
4537 c = getchar ();
4538 /* Try to read a label. */
4539 while (c != EOF && symbol_alphabet[c])
4541 if (i >= MBUF_SIZE-1)
4542 break;
4543 mbuffer[i++] = c;
4544 c = getchar ();
4546 if (i > 0)
4548 int skip_first = 0;
4550 if (mbuffer[0] == '.')
4551 ++skip_first;
4552 if (strip_underscore && mbuffer[skip_first] == '_')
4553 ++skip_first;
4555 if (skip_first > i)
4556 skip_first = i;
4558 mbuffer[i] = 0;
4560 result = cplus_demangle (mbuffer + skip_first, flags);
4561 if (result)
4563 if (mbuffer[0] == '.')
4564 putc ('.', stdout);
4565 fputs (result, stdout);
4566 free (result);
4568 else
4569 fputs (mbuffer, stdout);
4571 fflush (stdout);
4573 if (c == EOF)
4574 break;
4575 putchar (c);
4579 exit (0);
4582 static void
4583 fatal (str)
4584 char *str;
4586 fprintf (stderr, "%s: %s\n", program_name, str);
4587 exit (1);
4591 xmalloc (size)
4592 size_t size;
4594 register PTR value = (PTR) malloc (size);
4595 if (value == 0)
4596 fatal ("virtual memory exhausted");
4597 return value;
4601 xrealloc (ptr, size)
4602 PTR ptr;
4603 size_t size;
4605 register PTR value = (PTR) realloc (ptr, size);
4606 if (value == 0)
4607 fatal ("virtual memory exhausted");
4608 return value;
4610 #endif /* main */