MFC corrected printing of the slice number when adding a GPT partition.
[dragonfly.git] / contrib / gcc-3.4 / libiberty / cplus-dem.c
blobf3c4464f184ad9973e59ffd28273e47a585f1ba7
1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.uucp)
5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
8 This file is part of the libiberty library.
9 Libiberty is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 In addition to the permissions in the GNU Library General Public
15 License, the Free Software Foundation gives you unlimited permission
16 to link the compiled version of this file into combinations with other
17 programs, and to distribute those combinations without any restriction
18 coming from the use of this file. (The Library Public License
19 restrictions do apply in other respects; for example, they cover
20 modification of the file, and distribution when not linked into a
21 combined executable.)
23 Libiberty is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 Library General Public License for more details.
28 You should have received a copy of the GNU Library General Public
29 License along with libiberty; see the file COPYING.LIB. If
30 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
31 Boston, MA 02111-1307, USA. */
33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
35 This file imports xmalloc and xrealloc, which are like malloc and
36 realloc except that they generate a fatal error if there is no
37 available memory. */
39 /* This file lives in both GCC and libiberty. When making changes, please
40 try not to break either. */
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
46 #include "safe-ctype.h"
48 #include <sys/types.h>
49 #include <string.h>
50 #include <stdio.h>
52 #ifdef HAVE_STDLIB_H
53 #include <stdlib.h>
54 #else
55 char * malloc ();
56 char * realloc ();
57 #endif
59 #include <demangle.h>
60 #undef CURRENT_DEMANGLING_STYLE
61 #define CURRENT_DEMANGLING_STYLE work->options
63 #include "libiberty.h"
65 static char *ada_demangle PARAMS ((const char *, int));
67 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
69 /* A value at least one greater than the maximum number of characters
70 that will be output when using the `%d' format with `printf'. */
71 #define INTBUF_SIZE 32
73 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
75 /* In order to allow a single demangler executable to demangle strings
76 using various common values of CPLUS_MARKER, as well as any specific
77 one set at compile time, we maintain a string containing all the
78 commonly used ones, and check to see if the marker we are looking for
79 is in that string. CPLUS_MARKER is usually '$' on systems where the
80 assembler can deal with that. Where the assembler can't, it's usually
81 '.' (but on many systems '.' is used for other things). We put the
82 current defined CPLUS_MARKER first (which defaults to '$'), followed
83 by the next most common value, followed by an explicit '$' in case
84 the value of CPLUS_MARKER is not '$'.
86 We could avoid this if we could just get g++ to tell us what the actual
87 cplus marker character is as part of the debug information, perhaps by
88 ensuring that it is the character that terminates the gcc<n>_compiled
89 marker symbol (FIXME). */
91 #if !defined (CPLUS_MARKER)
92 #define CPLUS_MARKER '$'
93 #endif
95 enum demangling_styles current_demangling_style = auto_demangling;
97 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
99 static char char_str[2] = { '\000', '\000' };
101 void
102 set_cplus_marker_for_demangling (ch)
103 int ch;
105 cplus_markers[0] = ch;
108 typedef struct string /* Beware: these aren't required to be */
109 { /* '\0' terminated. */
110 char *b; /* pointer to start of string */
111 char *p; /* pointer after last character */
112 char *e; /* pointer after end of allocated space */
113 } string;
115 /* Stuff that is shared between sub-routines.
116 Using a shared structure allows cplus_demangle to be reentrant. */
118 struct work_stuff
120 int options;
121 char **typevec;
122 char **ktypevec;
123 char **btypevec;
124 int numk;
125 int numb;
126 int ksize;
127 int bsize;
128 int ntypes;
129 int typevec_size;
130 int constructor;
131 int destructor;
132 int static_type; /* A static member function */
133 int temp_start; /* index in demangled to start of template args */
134 int type_quals; /* The type qualifiers. */
135 int dllimported; /* Symbol imported from a PE DLL */
136 char **tmpl_argvec; /* Template function arguments. */
137 int ntmpl_args; /* The number of template function arguments. */
138 int forgetting_types; /* Nonzero if we are not remembering the types
139 we see. */
140 string* previous_argument; /* The last function argument demangled. */
141 int nrepeats; /* The number of times to repeat the previous
142 argument. */
145 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
146 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
148 static const struct optable
150 const char *const in;
151 const char *const out;
152 const int flags;
153 } optable[] = {
154 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
155 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
156 {"new", " new", 0}, /* old (1.91, and 1.x) */
157 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
158 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
159 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
160 {"as", "=", DMGL_ANSI}, /* ansi */
161 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
162 {"eq", "==", DMGL_ANSI}, /* old, ansi */
163 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
164 {"gt", ">", DMGL_ANSI}, /* old, ansi */
165 {"le", "<=", DMGL_ANSI}, /* old, ansi */
166 {"lt", "<", DMGL_ANSI}, /* old, ansi */
167 {"plus", "+", 0}, /* old */
168 {"pl", "+", DMGL_ANSI}, /* ansi */
169 {"apl", "+=", DMGL_ANSI}, /* ansi */
170 {"minus", "-", 0}, /* old */
171 {"mi", "-", DMGL_ANSI}, /* ansi */
172 {"ami", "-=", DMGL_ANSI}, /* ansi */
173 {"mult", "*", 0}, /* old */
174 {"ml", "*", DMGL_ANSI}, /* ansi */
175 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
176 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
177 {"convert", "+", 0}, /* old (unary +) */
178 {"negate", "-", 0}, /* old (unary -) */
179 {"trunc_mod", "%", 0}, /* old */
180 {"md", "%", DMGL_ANSI}, /* ansi */
181 {"amd", "%=", DMGL_ANSI}, /* ansi */
182 {"trunc_div", "/", 0}, /* old */
183 {"dv", "/", DMGL_ANSI}, /* ansi */
184 {"adv", "/=", DMGL_ANSI}, /* ansi */
185 {"truth_andif", "&&", 0}, /* old */
186 {"aa", "&&", DMGL_ANSI}, /* ansi */
187 {"truth_orif", "||", 0}, /* old */
188 {"oo", "||", DMGL_ANSI}, /* ansi */
189 {"truth_not", "!", 0}, /* old */
190 {"nt", "!", DMGL_ANSI}, /* ansi */
191 {"postincrement","++", 0}, /* old */
192 {"pp", "++", DMGL_ANSI}, /* ansi */
193 {"postdecrement","--", 0}, /* old */
194 {"mm", "--", DMGL_ANSI}, /* ansi */
195 {"bit_ior", "|", 0}, /* old */
196 {"or", "|", DMGL_ANSI}, /* ansi */
197 {"aor", "|=", DMGL_ANSI}, /* ansi */
198 {"bit_xor", "^", 0}, /* old */
199 {"er", "^", DMGL_ANSI}, /* ansi */
200 {"aer", "^=", DMGL_ANSI}, /* ansi */
201 {"bit_and", "&", 0}, /* old */
202 {"ad", "&", DMGL_ANSI}, /* ansi */
203 {"aad", "&=", DMGL_ANSI}, /* ansi */
204 {"bit_not", "~", 0}, /* old */
205 {"co", "~", DMGL_ANSI}, /* ansi */
206 {"call", "()", 0}, /* old */
207 {"cl", "()", DMGL_ANSI}, /* ansi */
208 {"alshift", "<<", 0}, /* old */
209 {"ls", "<<", DMGL_ANSI}, /* ansi */
210 {"als", "<<=", DMGL_ANSI}, /* ansi */
211 {"arshift", ">>", 0}, /* old */
212 {"rs", ">>", DMGL_ANSI}, /* ansi */
213 {"ars", ">>=", DMGL_ANSI}, /* ansi */
214 {"component", "->", 0}, /* old */
215 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
216 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
217 {"indirect", "*", 0}, /* old */
218 {"method_call", "->()", 0}, /* old */
219 {"addr", "&", 0}, /* old (unary &) */
220 {"array", "[]", 0}, /* old */
221 {"vc", "[]", DMGL_ANSI}, /* ansi */
222 {"compound", ", ", 0}, /* old */
223 {"cm", ", ", DMGL_ANSI}, /* ansi */
224 {"cond", "?:", 0}, /* old */
225 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
226 {"max", ">?", 0}, /* old */
227 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
228 {"min", "<?", 0}, /* old */
229 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
230 {"nop", "", 0}, /* old (for operator=) */
231 {"rm", "->*", DMGL_ANSI}, /* ansi */
232 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
235 /* These values are used to indicate the various type varieties.
236 They are all non-zero so that they can be used as `success'
237 values. */
238 typedef enum type_kind_t
240 tk_none,
241 tk_pointer,
242 tk_reference,
243 tk_integral,
244 tk_bool,
245 tk_char,
246 tk_real
247 } type_kind_t;
249 const struct demangler_engine libiberty_demanglers[] =
252 NO_DEMANGLING_STYLE_STRING,
253 no_demangling,
254 "Demangling disabled"
258 AUTO_DEMANGLING_STYLE_STRING,
259 auto_demangling,
260 "Automatic selection based on executable"
264 GNU_DEMANGLING_STYLE_STRING,
265 gnu_demangling,
266 "GNU (g++) style demangling"
270 LUCID_DEMANGLING_STYLE_STRING,
271 lucid_demangling,
272 "Lucid (lcc) style demangling"
276 ARM_DEMANGLING_STYLE_STRING,
277 arm_demangling,
278 "ARM style demangling"
282 HP_DEMANGLING_STYLE_STRING,
283 hp_demangling,
284 "HP (aCC) style demangling"
288 EDG_DEMANGLING_STYLE_STRING,
289 edg_demangling,
290 "EDG style demangling"
294 GNU_V3_DEMANGLING_STYLE_STRING,
295 gnu_v3_demangling,
296 "GNU (g++) V3 ABI-style demangling"
300 JAVA_DEMANGLING_STYLE_STRING,
301 java_demangling,
302 "Java style demangling"
306 GNAT_DEMANGLING_STYLE_STRING,
307 gnat_demangling,
308 "GNAT style demangling"
312 NULL, unknown_demangling, NULL
316 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
317 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
318 string_append(str, " ");}
319 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
321 /* The scope separator appropriate for the language being demangled. */
323 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
325 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
326 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
328 /* Prototypes for local functions */
330 static void
331 delete_work_stuff PARAMS ((struct work_stuff *));
333 static void
334 delete_non_B_K_work_stuff PARAMS ((struct work_stuff *));
336 static char *
337 mop_up PARAMS ((struct work_stuff *, string *, int));
339 static void
340 squangle_mop_up PARAMS ((struct work_stuff *));
342 static void
343 work_stuff_copy_to_from PARAMS ((struct work_stuff *, struct work_stuff *));
345 #if 0
346 static int
347 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
348 #endif
350 static char *
351 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
353 static int
354 demangle_template_template_parm PARAMS ((struct work_stuff *work,
355 const char **, string *));
357 static int
358 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
359 string *, int, int));
361 static int
362 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
363 const char **));
365 static int
366 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
368 static int
369 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
370 int, int));
372 static int
373 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
375 static int
376 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
378 static int
379 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
381 static int
382 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
384 static int
385 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
387 static int
388 arm_special PARAMS ((const char **, string *));
390 static void
391 string_need PARAMS ((string *, int));
393 static void
394 string_delete PARAMS ((string *));
396 static void
397 string_init PARAMS ((string *));
399 static void
400 string_clear PARAMS ((string *));
402 #if 0
403 static int
404 string_empty PARAMS ((string *));
405 #endif
407 static void
408 string_append PARAMS ((string *, const char *));
410 static void
411 string_appends PARAMS ((string *, string *));
413 static void
414 string_appendn PARAMS ((string *, const char *, int));
416 static void
417 string_prepend PARAMS ((string *, const char *));
419 static void
420 string_prependn PARAMS ((string *, const char *, int));
422 static void
423 string_append_template_idx PARAMS ((string *, int));
425 static int
426 get_count PARAMS ((const char **, int *));
428 static int
429 consume_count PARAMS ((const char **));
431 static int
432 consume_count_with_underscores PARAMS ((const char**));
434 static int
435 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
437 static int
438 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
440 static int
441 do_type PARAMS ((struct work_stuff *, const char **, string *));
443 static int
444 do_arg PARAMS ((struct work_stuff *, const char **, string *));
446 static void
447 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
448 const char *));
450 static int
451 iterate_demangle_function PARAMS ((struct work_stuff *,
452 const char **, string *, const char *));
454 static void
455 remember_type PARAMS ((struct work_stuff *, const char *, int));
457 static void
458 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
460 static int
461 register_Btype PARAMS ((struct work_stuff *));
463 static void
464 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
466 static void
467 forget_types PARAMS ((struct work_stuff *));
469 static void
470 forget_B_and_K_types PARAMS ((struct work_stuff *));
472 static void
473 string_prepends PARAMS ((string *, string *));
475 static int
476 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
477 string*, type_kind_t));
479 static int
480 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
482 static int
483 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
485 static int
486 snarf_numeric_literal PARAMS ((const char **, string *));
488 /* There is a TYPE_QUAL value for each type qualifier. They can be
489 combined by bitwise-or to form the complete set of qualifiers for a
490 type. */
492 #define TYPE_UNQUALIFIED 0x0
493 #define TYPE_QUAL_CONST 0x1
494 #define TYPE_QUAL_VOLATILE 0x2
495 #define TYPE_QUAL_RESTRICT 0x4
497 static int
498 code_for_qualifier PARAMS ((int));
500 static const char*
501 qualifier_string PARAMS ((int));
503 static const char*
504 demangle_qualifier PARAMS ((int));
506 static int
507 demangle_expression PARAMS ((struct work_stuff *, const char **, string *,
508 type_kind_t));
510 static int
511 demangle_integral_value PARAMS ((struct work_stuff *, const char **,
512 string *));
514 static int
515 demangle_real_value PARAMS ((struct work_stuff *, const char **, string *));
517 static void
518 demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
519 string *));
521 static void
522 recursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
523 int));
525 static void
526 grow_vect PARAMS ((char **, size_t *, size_t, int));
528 /* Translate count to integer, consuming tokens in the process.
529 Conversion terminates on the first non-digit character.
531 Trying to consume something that isn't a count results in no
532 consumption of input and a return of -1.
534 Overflow consumes the rest of the digits, and returns -1. */
536 static int
537 consume_count (type)
538 const char **type;
540 int count = 0;
542 if (! ISDIGIT ((unsigned char)**type))
543 return -1;
545 while (ISDIGIT ((unsigned char)**type))
547 count *= 10;
549 /* Check for overflow.
550 We assume that count is represented using two's-complement;
551 no power of two is divisible by ten, so if an overflow occurs
552 when multiplying by ten, the result will not be a multiple of
553 ten. */
554 if ((count % 10) != 0)
556 while (ISDIGIT ((unsigned char) **type))
557 (*type)++;
558 return -1;
561 count += **type - '0';
562 (*type)++;
565 if (count < 0)
566 count = -1;
568 return (count);
572 /* Like consume_count, but for counts that are preceded and followed
573 by '_' if they are greater than 10. Also, -1 is returned for
574 failure, since 0 can be a valid value. */
576 static int
577 consume_count_with_underscores (mangled)
578 const char **mangled;
580 int idx;
582 if (**mangled == '_')
584 (*mangled)++;
585 if (!ISDIGIT ((unsigned char)**mangled))
586 return -1;
588 idx = consume_count (mangled);
589 if (**mangled != '_')
590 /* The trailing underscore was missing. */
591 return -1;
593 (*mangled)++;
595 else
597 if (**mangled < '0' || **mangled > '9')
598 return -1;
600 idx = **mangled - '0';
601 (*mangled)++;
604 return idx;
607 /* C is the code for a type-qualifier. Return the TYPE_QUAL
608 corresponding to this qualifier. */
610 static int
611 code_for_qualifier (c)
612 int c;
614 switch (c)
616 case 'C':
617 return TYPE_QUAL_CONST;
619 case 'V':
620 return TYPE_QUAL_VOLATILE;
622 case 'u':
623 return TYPE_QUAL_RESTRICT;
625 default:
626 break;
629 /* C was an invalid qualifier. */
630 abort ();
633 /* Return the string corresponding to the qualifiers given by
634 TYPE_QUALS. */
636 static const char*
637 qualifier_string (type_quals)
638 int type_quals;
640 switch (type_quals)
642 case TYPE_UNQUALIFIED:
643 return "";
645 case TYPE_QUAL_CONST:
646 return "const";
648 case TYPE_QUAL_VOLATILE:
649 return "volatile";
651 case TYPE_QUAL_RESTRICT:
652 return "__restrict";
654 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
655 return "const volatile";
657 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
658 return "const __restrict";
660 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
661 return "volatile __restrict";
663 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
664 return "const volatile __restrict";
666 default:
667 break;
670 /* TYPE_QUALS was an invalid qualifier set. */
671 abort ();
674 /* C is the code for a type-qualifier. Return the string
675 corresponding to this qualifier. This function should only be
676 called with a valid qualifier code. */
678 static const char*
679 demangle_qualifier (c)
680 int c;
682 return qualifier_string (code_for_qualifier (c));
686 cplus_demangle_opname (opname, result, options)
687 const char *opname;
688 char *result;
689 int options;
691 int len, len1, ret;
692 string type;
693 struct work_stuff work[1];
694 const char *tem;
696 len = strlen(opname);
697 result[0] = '\0';
698 ret = 0;
699 memset ((char *) work, 0, sizeof (work));
700 work->options = options;
702 if (opname[0] == '_' && opname[1] == '_'
703 && opname[2] == 'o' && opname[3] == 'p')
705 /* ANSI. */
706 /* type conversion operator. */
707 tem = opname + 4;
708 if (do_type (work, &tem, &type))
710 strcat (result, "operator ");
711 strncat (result, type.b, type.p - type.b);
712 string_delete (&type);
713 ret = 1;
716 else if (opname[0] == '_' && opname[1] == '_'
717 && ISLOWER((unsigned char)opname[2])
718 && ISLOWER((unsigned char)opname[3]))
720 if (opname[4] == '\0')
722 /* Operator. */
723 size_t i;
724 for (i = 0; i < ARRAY_SIZE (optable); i++)
726 if (strlen (optable[i].in) == 2
727 && memcmp (optable[i].in, opname + 2, 2) == 0)
729 strcat (result, "operator");
730 strcat (result, optable[i].out);
731 ret = 1;
732 break;
736 else
738 if (opname[2] == 'a' && opname[5] == '\0')
740 /* Assignment. */
741 size_t i;
742 for (i = 0; i < ARRAY_SIZE (optable); i++)
744 if (strlen (optable[i].in) == 3
745 && memcmp (optable[i].in, opname + 2, 3) == 0)
747 strcat (result, "operator");
748 strcat (result, optable[i].out);
749 ret = 1;
750 break;
756 else if (len >= 3
757 && opname[0] == 'o'
758 && opname[1] == 'p'
759 && strchr (cplus_markers, opname[2]) != NULL)
761 /* see if it's an assignment expression */
762 if (len >= 10 /* op$assign_ */
763 && memcmp (opname + 3, "assign_", 7) == 0)
765 size_t i;
766 for (i = 0; i < ARRAY_SIZE (optable); i++)
768 len1 = len - 10;
769 if ((int) strlen (optable[i].in) == len1
770 && memcmp (optable[i].in, opname + 10, len1) == 0)
772 strcat (result, "operator");
773 strcat (result, optable[i].out);
774 strcat (result, "=");
775 ret = 1;
776 break;
780 else
782 size_t i;
783 for (i = 0; i < ARRAY_SIZE (optable); i++)
785 len1 = len - 3;
786 if ((int) strlen (optable[i].in) == len1
787 && memcmp (optable[i].in, opname + 3, len1) == 0)
789 strcat (result, "operator");
790 strcat (result, optable[i].out);
791 ret = 1;
792 break;
797 else if (len >= 5 && memcmp (opname, "type", 4) == 0
798 && strchr (cplus_markers, opname[4]) != NULL)
800 /* type conversion operator */
801 tem = opname + 5;
802 if (do_type (work, &tem, &type))
804 strcat (result, "operator ");
805 strncat (result, type.b, type.p - type.b);
806 string_delete (&type);
807 ret = 1;
810 squangle_mop_up (work);
811 return ret;
815 /* Takes operator name as e.g. "++" and returns mangled
816 operator name (e.g. "postincrement_expr"), or NULL if not found.
818 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
819 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
821 const char *
822 cplus_mangle_opname (opname, options)
823 const char *opname;
824 int options;
826 size_t i;
827 int len;
829 len = strlen (opname);
830 for (i = 0; i < ARRAY_SIZE (optable); i++)
832 if ((int) strlen (optable[i].out) == len
833 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
834 && memcmp (optable[i].out, opname, len) == 0)
835 return optable[i].in;
837 return (0);
840 /* Add a routine to set the demangling style to be sure it is valid and
841 allow for any demangler initialization that maybe necessary. */
843 enum demangling_styles
844 cplus_demangle_set_style (style)
845 enum demangling_styles style;
847 const struct demangler_engine *demangler = libiberty_demanglers;
849 for (; demangler->demangling_style != unknown_demangling; ++demangler)
850 if (style == demangler->demangling_style)
852 current_demangling_style = style;
853 return current_demangling_style;
856 return unknown_demangling;
859 /* Do string name to style translation */
861 enum demangling_styles
862 cplus_demangle_name_to_style (name)
863 const char *name;
865 const struct demangler_engine *demangler = libiberty_demanglers;
867 for (; demangler->demangling_style != unknown_demangling; ++demangler)
868 if (strcmp (name, demangler->demangling_style_name) == 0)
869 return demangler->demangling_style;
871 return unknown_demangling;
874 /* char *cplus_demangle (const char *mangled, int options)
876 If MANGLED is a mangled function name produced by GNU C++, then
877 a pointer to a @code{malloc}ed string giving a C++ representation
878 of the name will be returned; otherwise NULL will be returned.
879 It is the caller's responsibility to free the string which
880 is returned.
882 The OPTIONS arg may contain one or more of the following bits:
884 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
885 included.
886 DMGL_PARAMS Function parameters are included.
888 For example,
890 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
891 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
892 cplus_demangle ("foo__1Ai", 0) => "A::foo"
894 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
895 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
896 cplus_demangle ("foo__1Afe", 0) => "A::foo"
898 Note that any leading underscores, or other such characters prepended by
899 the compilation system, are presumed to have already been stripped from
900 MANGLED. */
902 char *
903 cplus_demangle (mangled, options)
904 const char *mangled;
905 int options;
907 char *ret;
908 struct work_stuff work[1];
910 if (current_demangling_style == no_demangling)
911 return xstrdup (mangled);
913 memset ((char *) work, 0, sizeof (work));
914 work->options = options;
915 if ((work->options & DMGL_STYLE_MASK) == 0)
916 work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
918 /* The V3 ABI demangling is implemented elsewhere. */
919 if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
921 ret = cplus_demangle_v3 (mangled, work->options);
922 if (ret || GNU_V3_DEMANGLING)
923 return ret;
926 if (JAVA_DEMANGLING)
928 ret = java_demangle_v3 (mangled);
929 if (ret)
930 return ret;
933 if (GNAT_DEMANGLING)
934 return ada_demangle(mangled,options);
936 ret = internal_cplus_demangle (work, mangled);
937 squangle_mop_up (work);
938 return (ret);
942 /* Assuming *OLD_VECT points to an array of *SIZE objects of size
943 ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
944 updating *OLD_VECT and *SIZE as necessary. */
946 static void
947 grow_vect (old_vect, size, min_size, element_size)
948 char **old_vect;
949 size_t *size;
950 size_t min_size;
951 int element_size;
953 if (*size < min_size)
955 *size *= 2;
956 if (*size < min_size)
957 *size = min_size;
958 *old_vect = (void *) xrealloc (*old_vect, *size * element_size);
962 /* Demangle ada names:
963 1. Discard final __{DIGIT}+ or ${DIGIT}+
964 2. Convert other instances of embedded "__" to `.'.
965 3. Discard leading _ada_.
966 4. Remove everything after first ___ if it is followed by 'X'.
967 5. Put symbols that should be suppressed in <...> brackets.
968 The resulting string is valid until the next call of ada_demangle. */
970 static char *
971 ada_demangle (mangled, option)
972 const char *mangled;
973 int option ATTRIBUTE_UNUSED;
975 int i, j;
976 int len0;
977 const char* p;
978 char *demangled = NULL;
979 int at_start_name;
980 int changed;
981 size_t demangled_size = 0;
983 changed = 0;
985 if (strncmp (mangled, "_ada_", 5) == 0)
987 mangled += 5;
988 changed = 1;
991 if (mangled[0] == '_' || mangled[0] == '<')
992 goto Suppress;
994 p = strstr (mangled, "___");
995 if (p == NULL)
996 len0 = strlen (mangled);
997 else
999 if (p[3] == 'X')
1001 len0 = p - mangled;
1002 changed = 1;
1004 else
1005 goto Suppress;
1008 /* Make demangled big enough for possible expansion by operator name. */
1009 grow_vect (&demangled,
1010 &demangled_size, 2 * len0 + 1,
1011 sizeof (char));
1013 if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
1014 for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
1016 if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
1018 len0 = i - 1;
1019 changed = 1;
1021 else if (mangled[i] == '$')
1023 len0 = i;
1024 changed = 1;
1028 for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
1029 i += 1, j += 1)
1030 demangled[j] = mangled[i];
1032 at_start_name = 1;
1033 while (i < len0)
1035 at_start_name = 0;
1037 if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
1039 demangled[j] = '.';
1040 changed = at_start_name = 1;
1041 i += 2; j += 1;
1043 else
1045 demangled[j] = mangled[i];
1046 i += 1; j += 1;
1049 demangled[j] = '\000';
1051 for (i = 0; demangled[i] != '\0'; i += 1)
1052 if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
1053 goto Suppress;
1055 if (! changed)
1056 return NULL;
1057 else
1058 return demangled;
1060 Suppress:
1061 grow_vect (&demangled,
1062 &demangled_size, strlen (mangled) + 3,
1063 sizeof (char));
1065 if (mangled[0] == '<')
1066 strcpy (demangled, mangled);
1067 else
1068 sprintf (demangled, "<%s>", mangled);
1070 return demangled;
1073 /* This function performs most of what cplus_demangle use to do, but
1074 to be able to demangle a name with a B, K or n code, we need to
1075 have a longer term memory of what types have been seen. The original
1076 now initializes and cleans up the squangle code info, while internal
1077 calls go directly to this routine to avoid resetting that info. */
1079 static char *
1080 internal_cplus_demangle (work, mangled)
1081 struct work_stuff *work;
1082 const char *mangled;
1085 string decl;
1086 int success = 0;
1087 char *demangled = NULL;
1088 int s1, s2, s3, s4;
1089 s1 = work->constructor;
1090 s2 = work->destructor;
1091 s3 = work->static_type;
1092 s4 = work->type_quals;
1093 work->constructor = work->destructor = 0;
1094 work->type_quals = TYPE_UNQUALIFIED;
1095 work->dllimported = 0;
1097 if ((mangled != NULL) && (*mangled != '\0'))
1099 string_init (&decl);
1101 /* First check to see if gnu style demangling is active and if the
1102 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1103 recognize one of the gnu special forms rather than looking for a
1104 standard prefix. In particular, don't worry about whether there
1105 is a "__" string in the mangled string. Consider "_$_5__foo" for
1106 example. */
1108 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
1110 success = gnu_special (work, &mangled, &decl);
1112 if (!success)
1114 success = demangle_prefix (work, &mangled, &decl);
1116 if (success && (*mangled != '\0'))
1118 success = demangle_signature (work, &mangled, &decl);
1120 if (work->constructor == 2)
1122 string_prepend (&decl, "global constructors keyed to ");
1123 work->constructor = 0;
1125 else if (work->destructor == 2)
1127 string_prepend (&decl, "global destructors keyed to ");
1128 work->destructor = 0;
1130 else if (work->dllimported == 1)
1132 string_prepend (&decl, "import stub for ");
1133 work->dllimported = 0;
1135 demangled = mop_up (work, &decl, success);
1137 work->constructor = s1;
1138 work->destructor = s2;
1139 work->static_type = s3;
1140 work->type_quals = s4;
1141 return demangled;
1145 /* Clear out and squangling related storage */
1146 static void
1147 squangle_mop_up (work)
1148 struct work_stuff *work;
1150 /* clean up the B and K type mangling types. */
1151 forget_B_and_K_types (work);
1152 if (work -> btypevec != NULL)
1154 free ((char *) work -> btypevec);
1156 if (work -> ktypevec != NULL)
1158 free ((char *) work -> ktypevec);
1163 /* Copy the work state and storage. */
1165 static void
1166 work_stuff_copy_to_from (to, from)
1167 struct work_stuff *to;
1168 struct work_stuff *from;
1170 int i;
1172 delete_work_stuff (to);
1174 /* Shallow-copy scalars. */
1175 memcpy (to, from, sizeof (*to));
1177 /* Deep-copy dynamic storage. */
1178 if (from->typevec_size)
1179 to->typevec
1180 = (char **) xmalloc (from->typevec_size * sizeof (to->typevec[0]));
1182 for (i = 0; i < from->ntypes; i++)
1184 int len = strlen (from->typevec[i]) + 1;
1186 to->typevec[i] = xmalloc (len);
1187 memcpy (to->typevec[i], from->typevec[i], len);
1190 if (from->ksize)
1191 to->ktypevec
1192 = (char **) xmalloc (from->ksize * sizeof (to->ktypevec[0]));
1194 for (i = 0; i < from->numk; i++)
1196 int len = strlen (from->ktypevec[i]) + 1;
1198 to->ktypevec[i] = xmalloc (len);
1199 memcpy (to->ktypevec[i], from->ktypevec[i], len);
1202 if (from->bsize)
1203 to->btypevec
1204 = (char **) xmalloc (from->bsize * sizeof (to->btypevec[0]));
1206 for (i = 0; i < from->numb; i++)
1208 int len = strlen (from->btypevec[i]) + 1;
1210 to->btypevec[i] = xmalloc (len);
1211 memcpy (to->btypevec[i], from->btypevec[i], len);
1214 if (from->ntmpl_args)
1215 to->tmpl_argvec
1216 = (char **) xmalloc (from->ntmpl_args * sizeof (to->tmpl_argvec[0]));
1218 for (i = 0; i < from->ntmpl_args; i++)
1220 int len = strlen (from->tmpl_argvec[i]) + 1;
1222 to->tmpl_argvec[i] = xmalloc (len);
1223 memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
1226 if (from->previous_argument)
1228 to->previous_argument = (string*) xmalloc (sizeof (string));
1229 string_init (to->previous_argument);
1230 string_appends (to->previous_argument, from->previous_argument);
1235 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1237 static void
1238 delete_non_B_K_work_stuff (work)
1239 struct work_stuff *work;
1241 /* Discard the remembered types, if any. */
1243 forget_types (work);
1244 if (work -> typevec != NULL)
1246 free ((char *) work -> typevec);
1247 work -> typevec = NULL;
1248 work -> typevec_size = 0;
1250 if (work->tmpl_argvec)
1252 int i;
1254 for (i = 0; i < work->ntmpl_args; i++)
1255 if (work->tmpl_argvec[i])
1256 free ((char*) work->tmpl_argvec[i]);
1258 free ((char*) work->tmpl_argvec);
1259 work->tmpl_argvec = NULL;
1261 if (work->previous_argument)
1263 string_delete (work->previous_argument);
1264 free ((char*) work->previous_argument);
1265 work->previous_argument = NULL;
1270 /* Delete all dynamic storage in work_stuff. */
1271 static void
1272 delete_work_stuff (work)
1273 struct work_stuff *work;
1275 delete_non_B_K_work_stuff (work);
1276 squangle_mop_up (work);
1280 /* Clear out any mangled storage */
1282 static char *
1283 mop_up (work, declp, success)
1284 struct work_stuff *work;
1285 string *declp;
1286 int success;
1288 char *demangled = NULL;
1290 delete_non_B_K_work_stuff (work);
1292 /* If demangling was successful, ensure that the demangled string is null
1293 terminated and return it. Otherwise, free the demangling decl. */
1295 if (!success)
1297 string_delete (declp);
1299 else
1301 string_appendn (declp, "", 1);
1302 demangled = declp->b;
1304 return (demangled);
1309 LOCAL FUNCTION
1311 demangle_signature -- demangle the signature part of a mangled name
1313 SYNOPSIS
1315 static int
1316 demangle_signature (struct work_stuff *work, const char **mangled,
1317 string *declp);
1319 DESCRIPTION
1321 Consume and demangle the signature portion of the mangled name.
1323 DECLP is the string where demangled output is being built. At
1324 entry it contains the demangled root name from the mangled name
1325 prefix. I.E. either a demangled operator name or the root function
1326 name. In some special cases, it may contain nothing.
1328 *MANGLED points to the current unconsumed location in the mangled
1329 name. As tokens are consumed and demangling is performed, the
1330 pointer is updated to continuously point at the next token to
1331 be consumed.
1333 Demangling GNU style mangled names is nasty because there is no
1334 explicit token that marks the start of the outermost function
1335 argument list. */
1337 static int
1338 demangle_signature (work, mangled, declp)
1339 struct work_stuff *work;
1340 const char **mangled;
1341 string *declp;
1343 int success = 1;
1344 int func_done = 0;
1345 int expect_func = 0;
1346 int expect_return_type = 0;
1347 const char *oldmangled = NULL;
1348 string trawname;
1349 string tname;
1351 while (success && (**mangled != '\0'))
1353 switch (**mangled)
1355 case 'Q':
1356 oldmangled = *mangled;
1357 success = demangle_qualified (work, mangled, declp, 1, 0);
1358 if (success)
1359 remember_type (work, oldmangled, *mangled - oldmangled);
1360 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1361 expect_func = 1;
1362 oldmangled = NULL;
1363 break;
1365 case 'K':
1366 oldmangled = *mangled;
1367 success = demangle_qualified (work, mangled, declp, 1, 0);
1368 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1370 expect_func = 1;
1372 oldmangled = NULL;
1373 break;
1375 case 'S':
1376 /* Static member function */
1377 if (oldmangled == NULL)
1379 oldmangled = *mangled;
1381 (*mangled)++;
1382 work -> static_type = 1;
1383 break;
1385 case 'C':
1386 case 'V':
1387 case 'u':
1388 work->type_quals |= code_for_qualifier (**mangled);
1390 /* a qualified member function */
1391 if (oldmangled == NULL)
1392 oldmangled = *mangled;
1393 (*mangled)++;
1394 break;
1396 case 'L':
1397 /* Local class name follows after "Lnnn_" */
1398 if (HP_DEMANGLING)
1400 while (**mangled && (**mangled != '_'))
1401 (*mangled)++;
1402 if (!**mangled)
1403 success = 0;
1404 else
1405 (*mangled)++;
1407 else
1408 success = 0;
1409 break;
1411 case '0': case '1': case '2': case '3': case '4':
1412 case '5': case '6': case '7': case '8': case '9':
1413 if (oldmangled == NULL)
1415 oldmangled = *mangled;
1417 work->temp_start = -1; /* uppermost call to demangle_class */
1418 success = demangle_class (work, mangled, declp);
1419 if (success)
1421 remember_type (work, oldmangled, *mangled - oldmangled);
1423 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1425 /* EDG and others will have the "F", so we let the loop cycle
1426 if we are looking at one. */
1427 if (**mangled != 'F')
1428 expect_func = 1;
1430 oldmangled = NULL;
1431 break;
1433 case 'B':
1435 string s;
1436 success = do_type (work, mangled, &s);
1437 if (success)
1439 string_append (&s, SCOPE_STRING (work));
1440 string_prepends (declp, &s);
1441 string_delete (&s);
1443 oldmangled = NULL;
1444 expect_func = 1;
1446 break;
1448 case 'F':
1449 /* Function */
1450 /* ARM/HP style demangling includes a specific 'F' character after
1451 the class name. For GNU style, it is just implied. So we can
1452 safely just consume any 'F' at this point and be compatible
1453 with either style. */
1455 oldmangled = NULL;
1456 func_done = 1;
1457 (*mangled)++;
1459 /* For lucid/ARM/HP style we have to forget any types we might
1460 have remembered up to this point, since they were not argument
1461 types. GNU style considers all types seen as available for
1462 back references. See comment in demangle_args() */
1464 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1466 forget_types (work);
1468 success = demangle_args (work, mangled, declp);
1469 /* After picking off the function args, we expect to either
1470 find the function return type (preceded by an '_') or the
1471 end of the string. */
1472 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1474 ++(*mangled);
1475 /* At this level, we do not care about the return type. */
1476 success = do_type (work, mangled, &tname);
1477 string_delete (&tname);
1480 break;
1482 case 't':
1483 /* G++ Template */
1484 string_init(&trawname);
1485 string_init(&tname);
1486 if (oldmangled == NULL)
1488 oldmangled = *mangled;
1490 success = demangle_template (work, mangled, &tname,
1491 &trawname, 1, 1);
1492 if (success)
1494 remember_type (work, oldmangled, *mangled - oldmangled);
1496 string_append (&tname, SCOPE_STRING (work));
1498 string_prepends(declp, &tname);
1499 if (work -> destructor & 1)
1501 string_prepend (&trawname, "~");
1502 string_appends (declp, &trawname);
1503 work->destructor -= 1;
1505 if ((work->constructor & 1) || (work->destructor & 1))
1507 string_appends (declp, &trawname);
1508 work->constructor -= 1;
1510 string_delete(&trawname);
1511 string_delete(&tname);
1512 oldmangled = NULL;
1513 expect_func = 1;
1514 break;
1516 case '_':
1517 if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1519 /* Read the return type. */
1520 string return_type;
1522 (*mangled)++;
1523 success = do_type (work, mangled, &return_type);
1524 APPEND_BLANK (&return_type);
1526 string_prepends (declp, &return_type);
1527 string_delete (&return_type);
1528 break;
1530 else
1531 /* At the outermost level, we cannot have a return type specified,
1532 so if we run into another '_' at this point we are dealing with
1533 a mangled name that is either bogus, or has been mangled by
1534 some algorithm we don't know how to deal with. So just
1535 reject the entire demangling. */
1536 /* However, "_nnn" is an expected suffix for alternate entry point
1537 numbered nnn for a function, with HP aCC, so skip over that
1538 without reporting failure. pai/1997-09-04 */
1539 if (HP_DEMANGLING)
1541 (*mangled)++;
1542 while (**mangled && ISDIGIT ((unsigned char)**mangled))
1543 (*mangled)++;
1545 else
1546 success = 0;
1547 break;
1549 case 'H':
1550 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1552 /* A G++ template function. Read the template arguments. */
1553 success = demangle_template (work, mangled, declp, 0, 0,
1555 if (!(work->constructor & 1))
1556 expect_return_type = 1;
1557 (*mangled)++;
1558 break;
1560 else
1561 /* fall through */
1564 default:
1565 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1567 /* Assume we have stumbled onto the first outermost function
1568 argument token, and start processing args. */
1569 func_done = 1;
1570 success = demangle_args (work, mangled, declp);
1572 else
1574 /* Non-GNU demanglers use a specific token to mark the start
1575 of the outermost function argument tokens. Typically 'F',
1576 for ARM/HP-demangling, for example. So if we find something
1577 we are not prepared for, it must be an error. */
1578 success = 0;
1580 break;
1583 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1586 if (success && expect_func)
1588 func_done = 1;
1589 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1591 forget_types (work);
1593 success = demangle_args (work, mangled, declp);
1594 /* Since template include the mangling of their return types,
1595 we must set expect_func to 0 so that we don't try do
1596 demangle more arguments the next time we get here. */
1597 expect_func = 0;
1601 if (success && !func_done)
1603 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1605 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1606 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1607 first case, and need to ensure that the '(void)' gets added to
1608 the current declp. Note that with ARM/HP, the first case
1609 represents the name of a static data member 'foo::bar',
1610 which is in the current declp, so we leave it alone. */
1611 success = demangle_args (work, mangled, declp);
1614 if (success && PRINT_ARG_TYPES)
1616 if (work->static_type)
1617 string_append (declp, " static");
1618 if (work->type_quals != TYPE_UNQUALIFIED)
1620 APPEND_BLANK (declp);
1621 string_append (declp, qualifier_string (work->type_quals));
1625 return (success);
1628 #if 0
1630 static int
1631 demangle_method_args (work, mangled, declp)
1632 struct work_stuff *work;
1633 const char **mangled;
1634 string *declp;
1636 int success = 0;
1638 if (work -> static_type)
1640 string_append (declp, *mangled + 1);
1641 *mangled += strlen (*mangled);
1642 success = 1;
1644 else
1646 success = demangle_args (work, mangled, declp);
1648 return (success);
1651 #endif
1653 static int
1654 demangle_template_template_parm (work, mangled, tname)
1655 struct work_stuff *work;
1656 const char **mangled;
1657 string *tname;
1659 int i;
1660 int r;
1661 int need_comma = 0;
1662 int success = 1;
1663 string temp;
1665 string_append (tname, "template <");
1666 /* get size of template parameter list */
1667 if (get_count (mangled, &r))
1669 for (i = 0; i < r; i++)
1671 if (need_comma)
1673 string_append (tname, ", ");
1676 /* Z for type parameters */
1677 if (**mangled == 'Z')
1679 (*mangled)++;
1680 string_append (tname, "class");
1682 /* z for template parameters */
1683 else if (**mangled == 'z')
1685 (*mangled)++;
1686 success =
1687 demangle_template_template_parm (work, mangled, tname);
1688 if (!success)
1690 break;
1693 else
1695 /* temp is initialized in do_type */
1696 success = do_type (work, mangled, &temp);
1697 if (success)
1699 string_appends (tname, &temp);
1701 string_delete(&temp);
1702 if (!success)
1704 break;
1707 need_comma = 1;
1711 if (tname->p[-1] == '>')
1712 string_append (tname, " ");
1713 string_append (tname, "> class");
1714 return (success);
1717 static int
1718 demangle_expression (work, mangled, s, tk)
1719 struct work_stuff *work;
1720 const char** mangled;
1721 string* s;
1722 type_kind_t tk;
1724 int need_operator = 0;
1725 int success;
1727 success = 1;
1728 string_appendn (s, "(", 1);
1729 (*mangled)++;
1730 while (success && **mangled != 'W' && **mangled != '\0')
1732 if (need_operator)
1734 size_t i;
1735 size_t len;
1737 success = 0;
1739 len = strlen (*mangled);
1741 for (i = 0; i < ARRAY_SIZE (optable); ++i)
1743 size_t l = strlen (optable[i].in);
1745 if (l <= len
1746 && memcmp (optable[i].in, *mangled, l) == 0)
1748 string_appendn (s, " ", 1);
1749 string_append (s, optable[i].out);
1750 string_appendn (s, " ", 1);
1751 success = 1;
1752 (*mangled) += l;
1753 break;
1757 if (!success)
1758 break;
1760 else
1761 need_operator = 1;
1763 success = demangle_template_value_parm (work, mangled, s, tk);
1766 if (**mangled != 'W')
1767 success = 0;
1768 else
1770 string_appendn (s, ")", 1);
1771 (*mangled)++;
1774 return success;
1777 static int
1778 demangle_integral_value (work, mangled, s)
1779 struct work_stuff *work;
1780 const char** mangled;
1781 string* s;
1783 int success;
1785 if (**mangled == 'E')
1786 success = demangle_expression (work, mangled, s, tk_integral);
1787 else if (**mangled == 'Q' || **mangled == 'K')
1788 success = demangle_qualified (work, mangled, s, 0, 1);
1789 else
1791 int value;
1793 /* By default, we let the number decide whether we shall consume an
1794 underscore. */
1795 int multidigit_without_leading_underscore = 0;
1796 int leave_following_underscore = 0;
1798 success = 0;
1800 if (**mangled == '_')
1802 if (mangled[0][1] == 'm')
1804 /* Since consume_count_with_underscores does not handle the
1805 `m'-prefix we must do it here, using consume_count and
1806 adjusting underscores: we have to consume the underscore
1807 matching the prepended one. */
1808 multidigit_without_leading_underscore = 1;
1809 string_appendn (s, "-", 1);
1810 (*mangled) += 2;
1812 else
1814 /* Do not consume a following underscore;
1815 consume_count_with_underscores will consume what
1816 should be consumed. */
1817 leave_following_underscore = 1;
1820 else
1822 /* Negative numbers are indicated with a leading `m'. */
1823 if (**mangled == 'm')
1825 string_appendn (s, "-", 1);
1826 (*mangled)++;
1828 /* Since consume_count_with_underscores does not handle
1829 multi-digit numbers that do not start with an underscore,
1830 and this number can be an integer template parameter,
1831 we have to call consume_count. */
1832 multidigit_without_leading_underscore = 1;
1833 /* These multi-digit numbers never end on an underscore,
1834 so if there is one then don't eat it. */
1835 leave_following_underscore = 1;
1838 /* We must call consume_count if we expect to remove a trailing
1839 underscore, since consume_count_with_underscores expects
1840 the leading underscore (that we consumed) if it is to handle
1841 multi-digit numbers. */
1842 if (multidigit_without_leading_underscore)
1843 value = consume_count (mangled);
1844 else
1845 value = consume_count_with_underscores (mangled);
1847 if (value != -1)
1849 char buf[INTBUF_SIZE];
1850 sprintf (buf, "%d", value);
1851 string_append (s, buf);
1853 /* Numbers not otherwise delimited, might have an underscore
1854 appended as a delimeter, which we should skip.
1856 ??? This used to always remove a following underscore, which
1857 is wrong. If other (arbitrary) cases are followed by an
1858 underscore, we need to do something more radical. */
1860 if ((value > 9 || multidigit_without_leading_underscore)
1861 && ! leave_following_underscore
1862 && **mangled == '_')
1863 (*mangled)++;
1865 /* All is well. */
1866 success = 1;
1870 return success;
1873 /* Demangle the real value in MANGLED. */
1875 static int
1876 demangle_real_value (work, mangled, s)
1877 struct work_stuff *work;
1878 const char **mangled;
1879 string* s;
1881 if (**mangled == 'E')
1882 return demangle_expression (work, mangled, s, tk_real);
1884 if (**mangled == 'm')
1886 string_appendn (s, "-", 1);
1887 (*mangled)++;
1889 while (ISDIGIT ((unsigned char)**mangled))
1891 string_appendn (s, *mangled, 1);
1892 (*mangled)++;
1894 if (**mangled == '.') /* fraction */
1896 string_appendn (s, ".", 1);
1897 (*mangled)++;
1898 while (ISDIGIT ((unsigned char)**mangled))
1900 string_appendn (s, *mangled, 1);
1901 (*mangled)++;
1904 if (**mangled == 'e') /* exponent */
1906 string_appendn (s, "e", 1);
1907 (*mangled)++;
1908 while (ISDIGIT ((unsigned char)**mangled))
1910 string_appendn (s, *mangled, 1);
1911 (*mangled)++;
1915 return 1;
1918 static int
1919 demangle_template_value_parm (work, mangled, s, tk)
1920 struct work_stuff *work;
1921 const char **mangled;
1922 string* s;
1923 type_kind_t tk;
1925 int success = 1;
1927 if (**mangled == 'Y')
1929 /* The next argument is a template parameter. */
1930 int idx;
1932 (*mangled)++;
1933 idx = consume_count_with_underscores (mangled);
1934 if (idx == -1
1935 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1936 || consume_count_with_underscores (mangled) == -1)
1937 return -1;
1938 if (work->tmpl_argvec)
1939 string_append (s, work->tmpl_argvec[idx]);
1940 else
1941 string_append_template_idx (s, idx);
1943 else if (tk == tk_integral)
1944 success = demangle_integral_value (work, mangled, s);
1945 else if (tk == tk_char)
1947 char tmp[2];
1948 int val;
1949 if (**mangled == 'm')
1951 string_appendn (s, "-", 1);
1952 (*mangled)++;
1954 string_appendn (s, "'", 1);
1955 val = consume_count(mangled);
1956 if (val <= 0)
1957 success = 0;
1958 else
1960 tmp[0] = (char)val;
1961 tmp[1] = '\0';
1962 string_appendn (s, &tmp[0], 1);
1963 string_appendn (s, "'", 1);
1966 else if (tk == tk_bool)
1968 int val = consume_count (mangled);
1969 if (val == 0)
1970 string_appendn (s, "false", 5);
1971 else if (val == 1)
1972 string_appendn (s, "true", 4);
1973 else
1974 success = 0;
1976 else if (tk == tk_real)
1977 success = demangle_real_value (work, mangled, s);
1978 else if (tk == tk_pointer || tk == tk_reference)
1980 if (**mangled == 'Q')
1981 success = demangle_qualified (work, mangled, s,
1982 /*isfuncname=*/0,
1983 /*append=*/1);
1984 else
1986 int symbol_len = consume_count (mangled);
1987 if (symbol_len == -1)
1988 return -1;
1989 if (symbol_len == 0)
1990 string_appendn (s, "0", 1);
1991 else
1993 char *p = xmalloc (symbol_len + 1), *q;
1994 strncpy (p, *mangled, symbol_len);
1995 p [symbol_len] = '\0';
1996 /* We use cplus_demangle here, rather than
1997 internal_cplus_demangle, because the name of the entity
1998 mangled here does not make use of any of the squangling
1999 or type-code information we have built up thus far; it is
2000 mangled independently. */
2001 q = cplus_demangle (p, work->options);
2002 if (tk == tk_pointer)
2003 string_appendn (s, "&", 1);
2004 /* FIXME: Pointer-to-member constants should get a
2005 qualifying class name here. */
2006 if (q)
2008 string_append (s, q);
2009 free (q);
2011 else
2012 string_append (s, p);
2013 free (p);
2015 *mangled += symbol_len;
2019 return success;
2022 /* Demangle the template name in MANGLED. The full name of the
2023 template (e.g., S<int>) is placed in TNAME. The name without the
2024 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2025 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2026 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2027 the template is remembered in the list of back-referenceable
2028 types. */
2030 static int
2031 demangle_template (work, mangled, tname, trawname, is_type, remember)
2032 struct work_stuff *work;
2033 const char **mangled;
2034 string *tname;
2035 string *trawname;
2036 int is_type;
2037 int remember;
2039 int i;
2040 int r;
2041 int need_comma = 0;
2042 int success = 0;
2043 const char *start;
2044 int is_java_array = 0;
2045 string temp;
2047 (*mangled)++;
2048 if (is_type)
2050 start = *mangled;
2051 /* get template name */
2052 if (**mangled == 'z')
2054 int idx;
2055 (*mangled)++;
2056 (*mangled)++;
2058 idx = consume_count_with_underscores (mangled);
2059 if (idx == -1
2060 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2061 || consume_count_with_underscores (mangled) == -1)
2062 return (0);
2064 if (work->tmpl_argvec)
2066 string_append (tname, work->tmpl_argvec[idx]);
2067 if (trawname)
2068 string_append (trawname, work->tmpl_argvec[idx]);
2070 else
2072 string_append_template_idx (tname, idx);
2073 if (trawname)
2074 string_append_template_idx (trawname, idx);
2077 else
2079 if ((r = consume_count (mangled)) <= 0
2080 || (int) strlen (*mangled) < r)
2082 return (0);
2084 is_java_array = (work -> options & DMGL_JAVA)
2085 && strncmp (*mangled, "JArray1Z", 8) == 0;
2086 if (! is_java_array)
2088 string_appendn (tname, *mangled, r);
2090 if (trawname)
2091 string_appendn (trawname, *mangled, r);
2092 *mangled += r;
2095 if (!is_java_array)
2096 string_append (tname, "<");
2097 /* get size of template parameter list */
2098 if (!get_count (mangled, &r))
2100 return (0);
2102 if (!is_type)
2104 /* Create an array for saving the template argument values. */
2105 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
2106 work->ntmpl_args = r;
2107 for (i = 0; i < r; i++)
2108 work->tmpl_argvec[i] = 0;
2110 for (i = 0; i < r; i++)
2112 if (need_comma)
2114 string_append (tname, ", ");
2116 /* Z for type parameters */
2117 if (**mangled == 'Z')
2119 (*mangled)++;
2120 /* temp is initialized in do_type */
2121 success = do_type (work, mangled, &temp);
2122 if (success)
2124 string_appends (tname, &temp);
2126 if (!is_type)
2128 /* Save the template argument. */
2129 int len = temp.p - temp.b;
2130 work->tmpl_argvec[i] = xmalloc (len + 1);
2131 memcpy (work->tmpl_argvec[i], temp.b, len);
2132 work->tmpl_argvec[i][len] = '\0';
2135 string_delete(&temp);
2136 if (!success)
2138 break;
2141 /* z for template parameters */
2142 else if (**mangled == 'z')
2144 int r2;
2145 (*mangled)++;
2146 success = demangle_template_template_parm (work, mangled, tname);
2148 if (success
2149 && (r2 = consume_count (mangled)) > 0
2150 && (int) strlen (*mangled) >= r2)
2152 string_append (tname, " ");
2153 string_appendn (tname, *mangled, r2);
2154 if (!is_type)
2156 /* Save the template argument. */
2157 int len = r2;
2158 work->tmpl_argvec[i] = xmalloc (len + 1);
2159 memcpy (work->tmpl_argvec[i], *mangled, len);
2160 work->tmpl_argvec[i][len] = '\0';
2162 *mangled += r2;
2164 if (!success)
2166 break;
2169 else
2171 string param;
2172 string* s;
2174 /* otherwise, value parameter */
2176 /* temp is initialized in do_type */
2177 success = do_type (work, mangled, &temp);
2178 string_delete(&temp);
2179 if (!success)
2180 break;
2182 if (!is_type)
2184 s = &param;
2185 string_init (s);
2187 else
2188 s = tname;
2190 success = demangle_template_value_parm (work, mangled, s,
2191 (type_kind_t) success);
2193 if (!success)
2195 if (!is_type)
2196 string_delete (s);
2197 success = 0;
2198 break;
2201 if (!is_type)
2203 int len = s->p - s->b;
2204 work->tmpl_argvec[i] = xmalloc (len + 1);
2205 memcpy (work->tmpl_argvec[i], s->b, len);
2206 work->tmpl_argvec[i][len] = '\0';
2208 string_appends (tname, s);
2209 string_delete (s);
2212 need_comma = 1;
2214 if (is_java_array)
2216 string_append (tname, "[]");
2218 else
2220 if (tname->p[-1] == '>')
2221 string_append (tname, " ");
2222 string_append (tname, ">");
2225 if (is_type && remember)
2227 const int bindex = register_Btype (work);
2228 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
2232 if (work -> static_type)
2234 string_append (declp, *mangled + 1);
2235 *mangled += strlen (*mangled);
2236 success = 1;
2238 else
2240 success = demangle_args (work, mangled, declp);
2244 return (success);
2247 static int
2248 arm_pt (work, mangled, n, anchor, args)
2249 struct work_stuff *work;
2250 const char *mangled;
2251 int n;
2252 const char **anchor, **args;
2254 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2255 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2256 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
2258 int len;
2259 *args = *anchor + 6;
2260 len = consume_count (args);
2261 if (len == -1)
2262 return 0;
2263 if (*args + len == mangled + n && **args == '_')
2265 ++*args;
2266 return 1;
2269 if (AUTO_DEMANGLING || EDG_DEMANGLING)
2271 if ((*anchor = strstr (mangled, "__tm__"))
2272 || (*anchor = strstr (mangled, "__ps__"))
2273 || (*anchor = strstr (mangled, "__pt__")))
2275 int len;
2276 *args = *anchor + 6;
2277 len = consume_count (args);
2278 if (len == -1)
2279 return 0;
2280 if (*args + len == mangled + n && **args == '_')
2282 ++*args;
2283 return 1;
2286 else if ((*anchor = strstr (mangled, "__S")))
2288 int len;
2289 *args = *anchor + 3;
2290 len = consume_count (args);
2291 if (len == -1)
2292 return 0;
2293 if (*args + len == mangled + n && **args == '_')
2295 ++*args;
2296 return 1;
2301 return 0;
2304 static void
2305 demangle_arm_hp_template (work, mangled, n, declp)
2306 struct work_stuff *work;
2307 const char **mangled;
2308 int n;
2309 string *declp;
2311 const char *p;
2312 const char *args;
2313 const char *e = *mangled + n;
2314 string arg;
2316 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2317 template args */
2318 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
2320 char *start_spec_args = NULL;
2321 int hold_options;
2323 /* First check for and omit template specialization pseudo-arguments,
2324 such as in "Spec<#1,#1.*>" */
2325 start_spec_args = strchr (*mangled, '<');
2326 if (start_spec_args && (start_spec_args - *mangled < n))
2327 string_appendn (declp, *mangled, start_spec_args - *mangled);
2328 else
2329 string_appendn (declp, *mangled, n);
2330 (*mangled) += n + 1;
2331 string_init (&arg);
2332 if (work->temp_start == -1) /* non-recursive call */
2333 work->temp_start = declp->p - declp->b;
2335 /* We want to unconditionally demangle parameter types in
2336 template parameters. */
2337 hold_options = work->options;
2338 work->options |= DMGL_PARAMS;
2340 string_append (declp, "<");
2341 while (1)
2343 string_delete (&arg);
2344 switch (**mangled)
2346 case 'T':
2347 /* 'T' signals a type parameter */
2348 (*mangled)++;
2349 if (!do_type (work, mangled, &arg))
2350 goto hpacc_template_args_done;
2351 break;
2353 case 'U':
2354 case 'S':
2355 /* 'U' or 'S' signals an integral value */
2356 if (!do_hpacc_template_const_value (work, mangled, &arg))
2357 goto hpacc_template_args_done;
2358 break;
2360 case 'A':
2361 /* 'A' signals a named constant expression (literal) */
2362 if (!do_hpacc_template_literal (work, mangled, &arg))
2363 goto hpacc_template_args_done;
2364 break;
2366 default:
2367 /* Today, 1997-09-03, we have only the above types
2368 of template parameters */
2369 /* FIXME: maybe this should fail and return null */
2370 goto hpacc_template_args_done;
2372 string_appends (declp, &arg);
2373 /* Check if we're at the end of template args.
2374 0 if at end of static member of template class,
2375 _ if done with template args for a function */
2376 if ((**mangled == '\000') || (**mangled == '_'))
2377 break;
2378 else
2379 string_append (declp, ",");
2381 hpacc_template_args_done:
2382 string_append (declp, ">");
2383 string_delete (&arg);
2384 if (**mangled == '_')
2385 (*mangled)++;
2386 work->options = hold_options;
2387 return;
2389 /* ARM template? (Also handles HP cfront extensions) */
2390 else if (arm_pt (work, *mangled, n, &p, &args))
2392 int hold_options;
2393 string type_str;
2395 string_init (&arg);
2396 string_appendn (declp, *mangled, p - *mangled);
2397 if (work->temp_start == -1) /* non-recursive call */
2398 work->temp_start = declp->p - declp->b;
2400 /* We want to unconditionally demangle parameter types in
2401 template parameters. */
2402 hold_options = work->options;
2403 work->options |= DMGL_PARAMS;
2405 string_append (declp, "<");
2406 /* should do error checking here */
2407 while (args < e) {
2408 string_delete (&arg);
2410 /* Check for type or literal here */
2411 switch (*args)
2413 /* HP cfront extensions to ARM for template args */
2414 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2415 /* FIXME: We handle only numeric literals for HP cfront */
2416 case 'X':
2417 /* A typed constant value follows */
2418 args++;
2419 if (!do_type (work, &args, &type_str))
2420 goto cfront_template_args_done;
2421 string_append (&arg, "(");
2422 string_appends (&arg, &type_str);
2423 string_delete (&type_str);
2424 string_append (&arg, ")");
2425 if (*args != 'L')
2426 goto cfront_template_args_done;
2427 args++;
2428 /* Now snarf a literal value following 'L' */
2429 if (!snarf_numeric_literal (&args, &arg))
2430 goto cfront_template_args_done;
2431 break;
2433 case 'L':
2434 /* Snarf a literal following 'L' */
2435 args++;
2436 if (!snarf_numeric_literal (&args, &arg))
2437 goto cfront_template_args_done;
2438 break;
2439 default:
2440 /* Not handling other HP cfront stuff */
2442 const char* old_args = args;
2443 if (!do_type (work, &args, &arg))
2444 goto cfront_template_args_done;
2446 /* Fail if we didn't make any progress: prevent infinite loop. */
2447 if (args == old_args)
2449 work->options = hold_options;
2450 return;
2454 string_appends (declp, &arg);
2455 string_append (declp, ",");
2457 cfront_template_args_done:
2458 string_delete (&arg);
2459 if (args >= e)
2460 --declp->p; /* remove extra comma */
2461 string_append (declp, ">");
2462 work->options = hold_options;
2464 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2465 && (*mangled)[9] == 'N'
2466 && (*mangled)[8] == (*mangled)[10]
2467 && strchr (cplus_markers, (*mangled)[8]))
2469 /* A member of the anonymous namespace. */
2470 string_append (declp, "{anonymous}");
2472 else
2474 if (work->temp_start == -1) /* non-recursive call only */
2475 work->temp_start = 0; /* disable in recursive calls */
2476 string_appendn (declp, *mangled, n);
2478 *mangled += n;
2481 /* Extract a class name, possibly a template with arguments, from the
2482 mangled string; qualifiers, local class indicators, etc. have
2483 already been dealt with */
2485 static int
2486 demangle_class_name (work, mangled, declp)
2487 struct work_stuff *work;
2488 const char **mangled;
2489 string *declp;
2491 int n;
2492 int success = 0;
2494 n = consume_count (mangled);
2495 if (n == -1)
2496 return 0;
2497 if ((int) strlen (*mangled) >= n)
2499 demangle_arm_hp_template (work, mangled, n, declp);
2500 success = 1;
2503 return (success);
2508 LOCAL FUNCTION
2510 demangle_class -- demangle a mangled class sequence
2512 SYNOPSIS
2514 static int
2515 demangle_class (struct work_stuff *work, const char **mangled,
2516 strint *declp)
2518 DESCRIPTION
2520 DECLP points to the buffer into which demangling is being done.
2522 *MANGLED points to the current token to be demangled. On input,
2523 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2524 On exit, it points to the next token after the mangled class on
2525 success, or the first unconsumed token on failure.
2527 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2528 we are demangling a constructor or destructor. In this case
2529 we prepend "class::class" or "class::~class" to DECLP.
2531 Otherwise, we prepend "class::" to the current DECLP.
2533 Reset the constructor/destructor flags once they have been
2534 "consumed". This allows demangle_class to be called later during
2535 the same demangling, to do normal class demangling.
2537 Returns 1 if demangling is successful, 0 otherwise.
2541 static int
2542 demangle_class (work, mangled, declp)
2543 struct work_stuff *work;
2544 const char **mangled;
2545 string *declp;
2547 int success = 0;
2548 int btype;
2549 string class_name;
2550 char *save_class_name_end = 0;
2552 string_init (&class_name);
2553 btype = register_Btype (work);
2554 if (demangle_class_name (work, mangled, &class_name))
2556 save_class_name_end = class_name.p;
2557 if ((work->constructor & 1) || (work->destructor & 1))
2559 /* adjust so we don't include template args */
2560 if (work->temp_start && (work->temp_start != -1))
2562 class_name.p = class_name.b + work->temp_start;
2564 string_prepends (declp, &class_name);
2565 if (work -> destructor & 1)
2567 string_prepend (declp, "~");
2568 work -> destructor -= 1;
2570 else
2572 work -> constructor -= 1;
2575 class_name.p = save_class_name_end;
2576 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2577 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2578 string_prepend (declp, SCOPE_STRING (work));
2579 string_prepends (declp, &class_name);
2580 success = 1;
2582 string_delete (&class_name);
2583 return (success);
2587 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2588 the rightmost guess.
2590 Find the correct "__"-sequence where the function name ends and the
2591 signature starts, which is ambiguous with GNU mangling.
2592 Call demangle_signature here, so we can make sure we found the right
2593 one; *mangled will be consumed so caller will not make further calls to
2594 demangle_signature. */
2596 static int
2597 iterate_demangle_function (work, mangled, declp, scan)
2598 struct work_stuff *work;
2599 const char **mangled;
2600 string *declp;
2601 const char *scan;
2603 const char *mangle_init = *mangled;
2604 int success = 0;
2605 string decl_init;
2606 struct work_stuff work_init;
2608 if (*(scan + 2) == '\0')
2609 return 0;
2611 /* Do not iterate for some demangling modes, or if there's only one
2612 "__"-sequence. This is the normal case. */
2613 if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2614 || strstr (scan + 2, "__") == NULL)
2616 demangle_function_name (work, mangled, declp, scan);
2617 return 1;
2620 /* Save state so we can restart if the guess at the correct "__" was
2621 wrong. */
2622 string_init (&decl_init);
2623 string_appends (&decl_init, declp);
2624 memset (&work_init, 0, sizeof work_init);
2625 work_stuff_copy_to_from (&work_init, work);
2627 /* Iterate over occurrences of __, allowing names and types to have a
2628 "__" sequence in them. We must start with the first (not the last)
2629 occurrence, since "__" most often occur between independent mangled
2630 parts, hence starting at the last occurence inside a signature
2631 might get us a "successful" demangling of the signature. */
2633 while (scan[2])
2635 demangle_function_name (work, mangled, declp, scan);
2636 success = demangle_signature (work, mangled, declp);
2637 if (success)
2638 break;
2640 /* Reset demangle state for the next round. */
2641 *mangled = mangle_init;
2642 string_clear (declp);
2643 string_appends (declp, &decl_init);
2644 work_stuff_copy_to_from (work, &work_init);
2646 /* Leave this underscore-sequence. */
2647 scan += 2;
2649 /* Scan for the next "__" sequence. */
2650 while (*scan && (scan[0] != '_' || scan[1] != '_'))
2651 scan++;
2653 /* Move to last "__" in this sequence. */
2654 while (*scan && *scan == '_')
2655 scan++;
2656 scan -= 2;
2659 /* Delete saved state. */
2660 delete_work_stuff (&work_init);
2661 string_delete (&decl_init);
2663 return success;
2668 LOCAL FUNCTION
2670 demangle_prefix -- consume the mangled name prefix and find signature
2672 SYNOPSIS
2674 static int
2675 demangle_prefix (struct work_stuff *work, const char **mangled,
2676 string *declp);
2678 DESCRIPTION
2680 Consume and demangle the prefix of the mangled name.
2681 While processing the function name root, arrange to call
2682 demangle_signature if the root is ambiguous.
2684 DECLP points to the string buffer into which demangled output is
2685 placed. On entry, the buffer is empty. On exit it contains
2686 the root function name, the demangled operator name, or in some
2687 special cases either nothing or the completely demangled result.
2689 MANGLED points to the current pointer into the mangled name. As each
2690 token of the mangled name is consumed, it is updated. Upon entry
2691 the current mangled name pointer points to the first character of
2692 the mangled name. Upon exit, it should point to the first character
2693 of the signature if demangling was successful, or to the first
2694 unconsumed character if demangling of the prefix was unsuccessful.
2696 Returns 1 on success, 0 otherwise.
2699 static int
2700 demangle_prefix (work, mangled, declp)
2701 struct work_stuff *work;
2702 const char **mangled;
2703 string *declp;
2705 int success = 1;
2706 const char *scan;
2707 int i;
2709 if (strlen(*mangled) > 6
2710 && (strncmp(*mangled, "_imp__", 6) == 0
2711 || strncmp(*mangled, "__imp_", 6) == 0))
2713 /* it's a symbol imported from a PE dynamic library. Check for both
2714 new style prefix _imp__ and legacy __imp_ used by older versions
2715 of dlltool. */
2716 (*mangled) += 6;
2717 work->dllimported = 1;
2719 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2721 char *marker = strchr (cplus_markers, (*mangled)[8]);
2722 if (marker != NULL && *marker == (*mangled)[10])
2724 if ((*mangled)[9] == 'D')
2726 /* it's a GNU global destructor to be executed at program exit */
2727 (*mangled) += 11;
2728 work->destructor = 2;
2729 if (gnu_special (work, mangled, declp))
2730 return success;
2732 else if ((*mangled)[9] == 'I')
2734 /* it's a GNU global constructor to be executed at program init */
2735 (*mangled) += 11;
2736 work->constructor = 2;
2737 if (gnu_special (work, mangled, declp))
2738 return success;
2742 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2744 /* it's a ARM global destructor to be executed at program exit */
2745 (*mangled) += 7;
2746 work->destructor = 2;
2748 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2750 /* it's a ARM global constructor to be executed at program initial */
2751 (*mangled) += 7;
2752 work->constructor = 2;
2755 /* This block of code is a reduction in strength time optimization
2757 scan = strstr (*mangled, "__"); */
2760 scan = *mangled;
2762 do {
2763 scan = strchr (scan, '_');
2764 } while (scan != NULL && *++scan != '_');
2766 if (scan != NULL) --scan;
2769 if (scan != NULL)
2771 /* We found a sequence of two or more '_', ensure that we start at
2772 the last pair in the sequence. */
2773 i = strspn (scan, "_");
2774 if (i > 2)
2776 scan += (i - 2);
2780 if (scan == NULL)
2782 success = 0;
2784 else if (work -> static_type)
2786 if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2788 success = 0;
2791 else if ((scan == *mangled)
2792 && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2793 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2795 /* The ARM says nothing about the mangling of local variables.
2796 But cfront mangles local variables by prepending __<nesting_level>
2797 to them. As an extension to ARM demangling we handle this case. */
2798 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2799 && ISDIGIT ((unsigned char)scan[2]))
2801 *mangled = scan + 2;
2802 consume_count (mangled);
2803 string_append (declp, *mangled);
2804 *mangled += strlen (*mangled);
2805 success = 1;
2807 else
2809 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2810 names like __Q2_3foo3bar for nested type names. So don't accept
2811 this style of constructor for cfront demangling. A GNU
2812 style member-template constructor starts with 'H'. */
2813 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2814 work -> constructor += 1;
2815 *mangled = scan + 2;
2818 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2820 /* Cfront-style parameterized type. Handled later as a signature. */
2821 success = 1;
2823 /* ARM template? */
2824 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2826 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2827 || (scan[2] == 'p' && scan[3] == 's')
2828 || (scan[2] == 'p' && scan[3] == 't')))
2830 /* EDG-style parameterized type. Handled later as a signature. */
2831 success = 1;
2833 /* EDG template? */
2834 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2836 else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2837 && (scan[2] != 't'))
2839 /* Mangled name starts with "__". Skip over any leading '_' characters,
2840 then find the next "__" that separates the prefix from the signature.
2842 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2843 || (arm_special (mangled, declp) == 0))
2845 while (*scan == '_')
2847 scan++;
2849 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2851 /* No separator (I.E. "__not_mangled"), or empty signature
2852 (I.E. "__not_mangled_either__") */
2853 success = 0;
2855 else
2856 return iterate_demangle_function (work, mangled, declp, scan);
2859 else if (*(scan + 2) != '\0')
2861 /* Mangled name does not start with "__" but does have one somewhere
2862 in there with non empty stuff after it. Looks like a global
2863 function name. Iterate over all "__":s until the right
2864 one is found. */
2865 return iterate_demangle_function (work, mangled, declp, scan);
2867 else
2869 /* Doesn't look like a mangled name */
2870 success = 0;
2873 if (!success && (work->constructor == 2 || work->destructor == 2))
2875 string_append (declp, *mangled);
2876 *mangled += strlen (*mangled);
2877 success = 1;
2879 return (success);
2884 LOCAL FUNCTION
2886 gnu_special -- special handling of gnu mangled strings
2888 SYNOPSIS
2890 static int
2891 gnu_special (struct work_stuff *work, const char **mangled,
2892 string *declp);
2895 DESCRIPTION
2897 Process some special GNU style mangling forms that don't fit
2898 the normal pattern. For example:
2900 _$_3foo (destructor for class foo)
2901 _vt$foo (foo virtual table)
2902 _vt$foo$bar (foo::bar virtual table)
2903 __vt_foo (foo virtual table, new style with thunks)
2904 _3foo$varname (static data member)
2905 _Q22rs2tu$vw (static data member)
2906 __t6vector1Zii (constructor with template)
2907 __thunk_4__$_7ostream (virtual function thunk)
2910 static int
2911 gnu_special (work, mangled, declp)
2912 struct work_stuff *work;
2913 const char **mangled;
2914 string *declp;
2916 int n;
2917 int success = 1;
2918 const char *p;
2920 if ((*mangled)[0] == '_'
2921 && strchr (cplus_markers, (*mangled)[1]) != NULL
2922 && (*mangled)[2] == '_')
2924 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2925 (*mangled) += 3;
2926 work -> destructor += 1;
2928 else if ((*mangled)[0] == '_'
2929 && (((*mangled)[1] == '_'
2930 && (*mangled)[2] == 'v'
2931 && (*mangled)[3] == 't'
2932 && (*mangled)[4] == '_')
2933 || ((*mangled)[1] == 'v'
2934 && (*mangled)[2] == 't'
2935 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2937 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2938 and create the decl. Note that we consume the entire mangled
2939 input string, which means that demangle_signature has no work
2940 to do. */
2941 if ((*mangled)[2] == 'v')
2942 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2943 else
2944 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2945 while (**mangled != '\0')
2947 switch (**mangled)
2949 case 'Q':
2950 case 'K':
2951 success = demangle_qualified (work, mangled, declp, 0, 1);
2952 break;
2953 case 't':
2954 success = demangle_template (work, mangled, declp, 0, 1,
2956 break;
2957 default:
2958 if (ISDIGIT((unsigned char)*mangled[0]))
2960 n = consume_count(mangled);
2961 /* We may be seeing a too-large size, or else a
2962 ".<digits>" indicating a static local symbol. In
2963 any case, declare victory and move on; *don't* try
2964 to use n to allocate. */
2965 if (n > (int) strlen (*mangled))
2967 success = 1;
2968 break;
2971 else
2973 n = strcspn (*mangled, cplus_markers);
2975 string_appendn (declp, *mangled, n);
2976 (*mangled) += n;
2979 p = strpbrk (*mangled, cplus_markers);
2980 if (success && ((p == NULL) || (p == *mangled)))
2982 if (p != NULL)
2984 string_append (declp, SCOPE_STRING (work));
2985 (*mangled)++;
2988 else
2990 success = 0;
2991 break;
2994 if (success)
2995 string_append (declp, " virtual table");
2997 else if ((*mangled)[0] == '_'
2998 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2999 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
3001 /* static data member, "_3foo$varname" for example */
3002 (*mangled)++;
3003 switch (**mangled)
3005 case 'Q':
3006 case 'K':
3007 success = demangle_qualified (work, mangled, declp, 0, 1);
3008 break;
3009 case 't':
3010 success = demangle_template (work, mangled, declp, 0, 1, 1);
3011 break;
3012 default:
3013 n = consume_count (mangled);
3014 if (n < 0 || n > (long) strlen (*mangled))
3016 success = 0;
3017 break;
3020 if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
3021 && (*mangled)[9] == 'N'
3022 && (*mangled)[8] == (*mangled)[10]
3023 && strchr (cplus_markers, (*mangled)[8]))
3025 /* A member of the anonymous namespace. There's information
3026 about what identifier or filename it was keyed to, but
3027 it's just there to make the mangled name unique; we just
3028 step over it. */
3029 string_append (declp, "{anonymous}");
3030 (*mangled) += n;
3032 /* Now p points to the marker before the N, so we need to
3033 update it to the first marker after what we consumed. */
3034 p = strpbrk (*mangled, cplus_markers);
3035 break;
3038 string_appendn (declp, *mangled, n);
3039 (*mangled) += n;
3041 if (success && (p == *mangled))
3043 /* Consumed everything up to the cplus_marker, append the
3044 variable name. */
3045 (*mangled)++;
3046 string_append (declp, SCOPE_STRING (work));
3047 n = strlen (*mangled);
3048 string_appendn (declp, *mangled, n);
3049 (*mangled) += n;
3051 else
3053 success = 0;
3056 else if (strncmp (*mangled, "__thunk_", 8) == 0)
3058 int delta;
3060 (*mangled) += 8;
3061 delta = consume_count (mangled);
3062 if (delta == -1)
3063 success = 0;
3064 else
3066 char *method = internal_cplus_demangle (work, ++*mangled);
3068 if (method)
3070 char buf[50];
3071 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
3072 string_append (declp, buf);
3073 string_append (declp, method);
3074 free (method);
3075 n = strlen (*mangled);
3076 (*mangled) += n;
3078 else
3080 success = 0;
3084 else if (strncmp (*mangled, "__t", 3) == 0
3085 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
3087 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
3088 (*mangled) += 4;
3089 switch (**mangled)
3091 case 'Q':
3092 case 'K':
3093 success = demangle_qualified (work, mangled, declp, 0, 1);
3094 break;
3095 case 't':
3096 success = demangle_template (work, mangled, declp, 0, 1, 1);
3097 break;
3098 default:
3099 success = do_type (work, mangled, declp);
3100 break;
3102 if (success && **mangled != '\0')
3103 success = 0;
3104 if (success)
3105 string_append (declp, p);
3107 else
3109 success = 0;
3111 return (success);
3114 static void
3115 recursively_demangle(work, mangled, result, namelength)
3116 struct work_stuff *work;
3117 const char **mangled;
3118 string *result;
3119 int namelength;
3121 char * recurse = (char *)NULL;
3122 char * recurse_dem = (char *)NULL;
3124 recurse = (char *) xmalloc (namelength + 1);
3125 memcpy (recurse, *mangled, namelength);
3126 recurse[namelength] = '\000';
3128 recurse_dem = cplus_demangle (recurse, work->options);
3130 if (recurse_dem)
3132 string_append (result, recurse_dem);
3133 free (recurse_dem);
3135 else
3137 string_appendn (result, *mangled, namelength);
3139 free (recurse);
3140 *mangled += namelength;
3145 LOCAL FUNCTION
3147 arm_special -- special handling of ARM/lucid mangled strings
3149 SYNOPSIS
3151 static int
3152 arm_special (const char **mangled,
3153 string *declp);
3156 DESCRIPTION
3158 Process some special ARM style mangling forms that don't fit
3159 the normal pattern. For example:
3161 __vtbl__3foo (foo virtual table)
3162 __vtbl__3foo__3bar (bar::foo virtual table)
3166 static int
3167 arm_special (mangled, declp)
3168 const char **mangled;
3169 string *declp;
3171 int n;
3172 int success = 1;
3173 const char *scan;
3175 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3177 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3178 and create the decl. Note that we consume the entire mangled
3179 input string, which means that demangle_signature has no work
3180 to do. */
3181 scan = *mangled + ARM_VTABLE_STRLEN;
3182 while (*scan != '\0') /* first check it can be demangled */
3184 n = consume_count (&scan);
3185 if (n == -1)
3187 return (0); /* no good */
3189 scan += n;
3190 if (scan[0] == '_' && scan[1] == '_')
3192 scan += 2;
3195 (*mangled) += ARM_VTABLE_STRLEN;
3196 while (**mangled != '\0')
3198 n = consume_count (mangled);
3199 if (n == -1
3200 || n > (long) strlen (*mangled))
3201 return 0;
3202 string_prependn (declp, *mangled, n);
3203 (*mangled) += n;
3204 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3206 string_prepend (declp, "::");
3207 (*mangled) += 2;
3210 string_append (declp, " virtual table");
3212 else
3214 success = 0;
3216 return (success);
3221 LOCAL FUNCTION
3223 demangle_qualified -- demangle 'Q' qualified name strings
3225 SYNOPSIS
3227 static int
3228 demangle_qualified (struct work_stuff *, const char *mangled,
3229 string *result, int isfuncname, int append);
3231 DESCRIPTION
3233 Demangle a qualified name, such as "Q25Outer5Inner" which is
3234 the mangled form of "Outer::Inner". The demangled output is
3235 prepended or appended to the result string according to the
3236 state of the append flag.
3238 If isfuncname is nonzero, then the qualified name we are building
3239 is going to be used as a member function name, so if it is a
3240 constructor or destructor function, append an appropriate
3241 constructor or destructor name. I.E. for the above example,
3242 the result for use as a constructor is "Outer::Inner::Inner"
3243 and the result for use as a destructor is "Outer::Inner::~Inner".
3245 BUGS
3247 Numeric conversion is ASCII dependent (FIXME).
3251 static int
3252 demangle_qualified (work, mangled, result, isfuncname, append)
3253 struct work_stuff *work;
3254 const char **mangled;
3255 string *result;
3256 int isfuncname;
3257 int append;
3259 int qualifiers = 0;
3260 int success = 1;
3261 char num[2];
3262 string temp;
3263 string last_name;
3264 int bindex = register_Btype (work);
3266 /* We only make use of ISFUNCNAME if the entity is a constructor or
3267 destructor. */
3268 isfuncname = (isfuncname
3269 && ((work->constructor & 1) || (work->destructor & 1)));
3271 string_init (&temp);
3272 string_init (&last_name);
3274 if ((*mangled)[0] == 'K')
3276 /* Squangling qualified name reuse */
3277 int idx;
3278 (*mangled)++;
3279 idx = consume_count_with_underscores (mangled);
3280 if (idx == -1 || idx >= work -> numk)
3281 success = 0;
3282 else
3283 string_append (&temp, work -> ktypevec[idx]);
3285 else
3286 switch ((*mangled)[1])
3288 case '_':
3289 /* GNU mangled name with more than 9 classes. The count is preceded
3290 by an underscore (to distinguish it from the <= 9 case) and followed
3291 by an underscore. */
3292 (*mangled)++;
3293 qualifiers = consume_count_with_underscores (mangled);
3294 if (qualifiers == -1)
3295 success = 0;
3296 break;
3298 case '1':
3299 case '2':
3300 case '3':
3301 case '4':
3302 case '5':
3303 case '6':
3304 case '7':
3305 case '8':
3306 case '9':
3307 /* The count is in a single digit. */
3308 num[0] = (*mangled)[1];
3309 num[1] = '\0';
3310 qualifiers = atoi (num);
3312 /* If there is an underscore after the digit, skip it. This is
3313 said to be for ARM-qualified names, but the ARM makes no
3314 mention of such an underscore. Perhaps cfront uses one. */
3315 if ((*mangled)[2] == '_')
3317 (*mangled)++;
3319 (*mangled) += 2;
3320 break;
3322 case '0':
3323 default:
3324 success = 0;
3327 if (!success)
3328 return success;
3330 /* Pick off the names and collect them in the temp buffer in the order
3331 in which they are found, separated by '::'. */
3333 while (qualifiers-- > 0)
3335 int remember_K = 1;
3336 string_clear (&last_name);
3338 if (*mangled[0] == '_')
3339 (*mangled)++;
3341 if (*mangled[0] == 't')
3343 /* Here we always append to TEMP since we will want to use
3344 the template name without the template parameters as a
3345 constructor or destructor name. The appropriate
3346 (parameter-less) value is returned by demangle_template
3347 in LAST_NAME. We do not remember the template type here,
3348 in order to match the G++ mangling algorithm. */
3349 success = demangle_template(work, mangled, &temp,
3350 &last_name, 1, 0);
3351 if (!success)
3352 break;
3354 else if (*mangled[0] == 'K')
3356 int idx;
3357 (*mangled)++;
3358 idx = consume_count_with_underscores (mangled);
3359 if (idx == -1 || idx >= work->numk)
3360 success = 0;
3361 else
3362 string_append (&temp, work->ktypevec[idx]);
3363 remember_K = 0;
3365 if (!success) break;
3367 else
3369 if (EDG_DEMANGLING)
3371 int namelength;
3372 /* Now recursively demangle the qualifier
3373 * This is necessary to deal with templates in
3374 * mangling styles like EDG */
3375 namelength = consume_count (mangled);
3376 if (namelength == -1)
3378 success = 0;
3379 break;
3381 recursively_demangle(work, mangled, &temp, namelength);
3383 else
3385 string_delete (&last_name);
3386 success = do_type (work, mangled, &last_name);
3387 if (!success)
3388 break;
3389 string_appends (&temp, &last_name);
3393 if (remember_K)
3394 remember_Ktype (work, temp.b, LEN_STRING (&temp));
3396 if (qualifiers > 0)
3397 string_append (&temp, SCOPE_STRING (work));
3400 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3402 /* If we are using the result as a function name, we need to append
3403 the appropriate '::' separated constructor or destructor name.
3404 We do this here because this is the most convenient place, where
3405 we already have a pointer to the name and the length of the name. */
3407 if (isfuncname)
3409 string_append (&temp, SCOPE_STRING (work));
3410 if (work -> destructor & 1)
3411 string_append (&temp, "~");
3412 string_appends (&temp, &last_name);
3415 /* Now either prepend the temp buffer to the result, or append it,
3416 depending upon the state of the append flag. */
3418 if (append)
3419 string_appends (result, &temp);
3420 else
3422 if (!STRING_EMPTY (result))
3423 string_append (&temp, SCOPE_STRING (work));
3424 string_prepends (result, &temp);
3427 string_delete (&last_name);
3428 string_delete (&temp);
3429 return (success);
3434 LOCAL FUNCTION
3436 get_count -- convert an ascii count to integer, consuming tokens
3438 SYNOPSIS
3440 static int
3441 get_count (const char **type, int *count)
3443 DESCRIPTION
3445 Assume that *type points at a count in a mangled name; set
3446 *count to its value, and set *type to the next character after
3447 the count. There are some weird rules in effect here.
3449 If *type does not point at a string of digits, return zero.
3451 If *type points at a string of digits followed by an
3452 underscore, set *count to their value as an integer, advance
3453 *type to point *after the underscore, and return 1.
3455 If *type points at a string of digits not followed by an
3456 underscore, consume only the first digit. Set *count to its
3457 value as an integer, leave *type pointing after that digit,
3458 and return 1.
3460 The excuse for this odd behavior: in the ARM and HP demangling
3461 styles, a type can be followed by a repeat count of the form
3462 `Nxy', where:
3464 `x' is a single digit specifying how many additional copies
3465 of the type to append to the argument list, and
3467 `y' is one or more digits, specifying the zero-based index of
3468 the first repeated argument in the list. Yes, as you're
3469 unmangling the name you can figure this out yourself, but
3470 it's there anyway.
3472 So, for example, in `bar__3fooFPiN51', the first argument is a
3473 pointer to an integer (`Pi'), and then the next five arguments
3474 are the same (`N5'), and the first repeat is the function's
3475 second argument (`1').
3478 static int
3479 get_count (type, count)
3480 const char **type;
3481 int *count;
3483 const char *p;
3484 int n;
3486 if (!ISDIGIT ((unsigned char)**type))
3487 return (0);
3488 else
3490 *count = **type - '0';
3491 (*type)++;
3492 if (ISDIGIT ((unsigned char)**type))
3494 p = *type;
3495 n = *count;
3498 n *= 10;
3499 n += *p - '0';
3500 p++;
3502 while (ISDIGIT ((unsigned char)*p));
3503 if (*p == '_')
3505 *type = p + 1;
3506 *count = n;
3510 return (1);
3513 /* RESULT will be initialised here; it will be freed on failure. The
3514 value returned is really a type_kind_t. */
3516 static int
3517 do_type (work, mangled, result)
3518 struct work_stuff *work;
3519 const char **mangled;
3520 string *result;
3522 int n;
3523 int done;
3524 int success;
3525 string decl;
3526 const char *remembered_type;
3527 int type_quals;
3528 type_kind_t tk = tk_none;
3530 string_init (&decl);
3531 string_init (result);
3533 done = 0;
3534 success = 1;
3535 while (success && !done)
3537 int member;
3538 switch (**mangled)
3541 /* A pointer type */
3542 case 'P':
3543 case 'p':
3544 (*mangled)++;
3545 if (! (work -> options & DMGL_JAVA))
3546 string_prepend (&decl, "*");
3547 if (tk == tk_none)
3548 tk = tk_pointer;
3549 break;
3551 /* A reference type */
3552 case 'R':
3553 (*mangled)++;
3554 string_prepend (&decl, "&");
3555 if (tk == tk_none)
3556 tk = tk_reference;
3557 break;
3559 /* An array */
3560 case 'A':
3562 ++(*mangled);
3563 if (!STRING_EMPTY (&decl)
3564 && (decl.b[0] == '*' || decl.b[0] == '&'))
3566 string_prepend (&decl, "(");
3567 string_append (&decl, ")");
3569 string_append (&decl, "[");
3570 if (**mangled != '_')
3571 success = demangle_template_value_parm (work, mangled, &decl,
3572 tk_integral);
3573 if (**mangled == '_')
3574 ++(*mangled);
3575 string_append (&decl, "]");
3576 break;
3579 /* A back reference to a previously seen type */
3580 case 'T':
3581 (*mangled)++;
3582 if (!get_count (mangled, &n) || n >= work -> ntypes)
3584 success = 0;
3586 else
3588 remembered_type = work -> typevec[n];
3589 mangled = &remembered_type;
3591 break;
3593 /* A function */
3594 case 'F':
3595 (*mangled)++;
3596 if (!STRING_EMPTY (&decl)
3597 && (decl.b[0] == '*' || decl.b[0] == '&'))
3599 string_prepend (&decl, "(");
3600 string_append (&decl, ")");
3602 /* After picking off the function args, we expect to either find the
3603 function return type (preceded by an '_') or the end of the
3604 string. */
3605 if (!demangle_nested_args (work, mangled, &decl)
3606 || (**mangled != '_' && **mangled != '\0'))
3608 success = 0;
3609 break;
3611 if (success && (**mangled == '_'))
3612 (*mangled)++;
3613 break;
3615 case 'M':
3616 case 'O':
3618 type_quals = TYPE_UNQUALIFIED;
3620 member = **mangled == 'M';
3621 (*mangled)++;
3623 string_append (&decl, ")");
3625 /* We don't need to prepend `::' for a qualified name;
3626 demangle_qualified will do that for us. */
3627 if (**mangled != 'Q')
3628 string_prepend (&decl, SCOPE_STRING (work));
3630 if (ISDIGIT ((unsigned char)**mangled))
3632 n = consume_count (mangled);
3633 if (n == -1
3634 || (int) strlen (*mangled) < n)
3636 success = 0;
3637 break;
3639 string_prependn (&decl, *mangled, n);
3640 *mangled += n;
3642 else if (**mangled == 'X' || **mangled == 'Y')
3644 string temp;
3645 do_type (work, mangled, &temp);
3646 string_prepends (&decl, &temp);
3647 string_delete (&temp);
3649 else if (**mangled == 't')
3651 string temp;
3652 string_init (&temp);
3653 success = demangle_template (work, mangled, &temp,
3654 NULL, 1, 1);
3655 if (success)
3657 string_prependn (&decl, temp.b, temp.p - temp.b);
3658 string_delete (&temp);
3660 else
3661 break;
3663 else if (**mangled == 'Q')
3665 success = demangle_qualified (work, mangled, &decl,
3666 /*isfuncnam=*/0,
3667 /*append=*/0);
3668 if (!success)
3669 break;
3671 else
3673 success = 0;
3674 break;
3677 string_prepend (&decl, "(");
3678 if (member)
3680 switch (**mangled)
3682 case 'C':
3683 case 'V':
3684 case 'u':
3685 type_quals |= code_for_qualifier (**mangled);
3686 (*mangled)++;
3687 break;
3689 default:
3690 break;
3693 if (*(*mangled)++ != 'F')
3695 success = 0;
3696 break;
3699 if ((member && !demangle_nested_args (work, mangled, &decl))
3700 || **mangled != '_')
3702 success = 0;
3703 break;
3705 (*mangled)++;
3706 if (! PRINT_ANSI_QUALIFIERS)
3708 break;
3710 if (type_quals != TYPE_UNQUALIFIED)
3712 APPEND_BLANK (&decl);
3713 string_append (&decl, qualifier_string (type_quals));
3715 break;
3717 case 'G':
3718 (*mangled)++;
3719 break;
3721 case 'C':
3722 case 'V':
3723 case 'u':
3724 if (PRINT_ANSI_QUALIFIERS)
3726 if (!STRING_EMPTY (&decl))
3727 string_prepend (&decl, " ");
3729 string_prepend (&decl, demangle_qualifier (**mangled));
3731 (*mangled)++;
3732 break;
3737 /* fall through */
3738 default:
3739 done = 1;
3740 break;
3744 if (success) switch (**mangled)
3746 /* A qualified name, such as "Outer::Inner". */
3747 case 'Q':
3748 case 'K':
3750 success = demangle_qualified (work, mangled, result, 0, 1);
3751 break;
3754 /* A back reference to a previously seen squangled type */
3755 case 'B':
3756 (*mangled)++;
3757 if (!get_count (mangled, &n) || n >= work -> numb)
3758 success = 0;
3759 else
3760 string_append (result, work->btypevec[n]);
3761 break;
3763 case 'X':
3764 case 'Y':
3765 /* A template parm. We substitute the corresponding argument. */
3767 int idx;
3769 (*mangled)++;
3770 idx = consume_count_with_underscores (mangled);
3772 if (idx == -1
3773 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3774 || consume_count_with_underscores (mangled) == -1)
3776 success = 0;
3777 break;
3780 if (work->tmpl_argvec)
3781 string_append (result, work->tmpl_argvec[idx]);
3782 else
3783 string_append_template_idx (result, idx);
3785 success = 1;
3787 break;
3789 default:
3790 success = demangle_fund_type (work, mangled, result);
3791 if (tk == tk_none)
3792 tk = (type_kind_t) success;
3793 break;
3796 if (success)
3798 if (!STRING_EMPTY (&decl))
3800 string_append (result, " ");
3801 string_appends (result, &decl);
3804 else
3805 string_delete (result);
3806 string_delete (&decl);
3808 if (success)
3809 /* Assume an integral type, if we're not sure. */
3810 return (int) ((tk == tk_none) ? tk_integral : tk);
3811 else
3812 return 0;
3815 /* Given a pointer to a type string that represents a fundamental type
3816 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3817 string in which the demangled output is being built in RESULT, and
3818 the WORK structure, decode the types and add them to the result.
3820 For example:
3822 "Ci" => "const int"
3823 "Sl" => "signed long"
3824 "CUs" => "const unsigned short"
3826 The value returned is really a type_kind_t. */
3828 static int
3829 demangle_fund_type (work, mangled, result)
3830 struct work_stuff *work;
3831 const char **mangled;
3832 string *result;
3834 int done = 0;
3835 int success = 1;
3836 char buf[10];
3837 unsigned int dec = 0;
3838 type_kind_t tk = tk_integral;
3840 /* First pick off any type qualifiers. There can be more than one. */
3842 while (!done)
3844 switch (**mangled)
3846 case 'C':
3847 case 'V':
3848 case 'u':
3849 if (PRINT_ANSI_QUALIFIERS)
3851 if (!STRING_EMPTY (result))
3852 string_prepend (result, " ");
3853 string_prepend (result, demangle_qualifier (**mangled));
3855 (*mangled)++;
3856 break;
3857 case 'U':
3858 (*mangled)++;
3859 APPEND_BLANK (result);
3860 string_append (result, "unsigned");
3861 break;
3862 case 'S': /* signed char only */
3863 (*mangled)++;
3864 APPEND_BLANK (result);
3865 string_append (result, "signed");
3866 break;
3867 case 'J':
3868 (*mangled)++;
3869 APPEND_BLANK (result);
3870 string_append (result, "__complex");
3871 break;
3872 default:
3873 done = 1;
3874 break;
3878 /* Now pick off the fundamental type. There can be only one. */
3880 switch (**mangled)
3882 case '\0':
3883 case '_':
3884 break;
3885 case 'v':
3886 (*mangled)++;
3887 APPEND_BLANK (result);
3888 string_append (result, "void");
3889 break;
3890 case 'x':
3891 (*mangled)++;
3892 APPEND_BLANK (result);
3893 string_append (result, "long long");
3894 break;
3895 case 'l':
3896 (*mangled)++;
3897 APPEND_BLANK (result);
3898 string_append (result, "long");
3899 break;
3900 case 'i':
3901 (*mangled)++;
3902 APPEND_BLANK (result);
3903 string_append (result, "int");
3904 break;
3905 case 's':
3906 (*mangled)++;
3907 APPEND_BLANK (result);
3908 string_append (result, "short");
3909 break;
3910 case 'b':
3911 (*mangled)++;
3912 APPEND_BLANK (result);
3913 string_append (result, "bool");
3914 tk = tk_bool;
3915 break;
3916 case 'c':
3917 (*mangled)++;
3918 APPEND_BLANK (result);
3919 string_append (result, "char");
3920 tk = tk_char;
3921 break;
3922 case 'w':
3923 (*mangled)++;
3924 APPEND_BLANK (result);
3925 string_append (result, "wchar_t");
3926 tk = tk_char;
3927 break;
3928 case 'r':
3929 (*mangled)++;
3930 APPEND_BLANK (result);
3931 string_append (result, "long double");
3932 tk = tk_real;
3933 break;
3934 case 'd':
3935 (*mangled)++;
3936 APPEND_BLANK (result);
3937 string_append (result, "double");
3938 tk = tk_real;
3939 break;
3940 case 'f':
3941 (*mangled)++;
3942 APPEND_BLANK (result);
3943 string_append (result, "float");
3944 tk = tk_real;
3945 break;
3946 case 'G':
3947 (*mangled)++;
3948 if (!ISDIGIT ((unsigned char)**mangled))
3950 success = 0;
3951 break;
3953 case 'I':
3954 (*mangled)++;
3955 if (**mangled == '_')
3957 int i;
3958 (*mangled)++;
3959 for (i = 0;
3960 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3961 (*mangled)++, i++)
3962 buf[i] = **mangled;
3963 if (**mangled != '_')
3965 success = 0;
3966 break;
3968 buf[i] = '\0';
3969 (*mangled)++;
3971 else
3973 strncpy (buf, *mangled, 2);
3974 buf[2] = '\0';
3975 *mangled += min (strlen (*mangled), 2);
3977 sscanf (buf, "%x", &dec);
3978 sprintf (buf, "int%u_t", dec);
3979 APPEND_BLANK (result);
3980 string_append (result, buf);
3981 break;
3983 /* fall through */
3984 /* An explicit type, such as "6mytype" or "7integer" */
3985 case '0':
3986 case '1':
3987 case '2':
3988 case '3':
3989 case '4':
3990 case '5':
3991 case '6':
3992 case '7':
3993 case '8':
3994 case '9':
3996 int bindex = register_Btype (work);
3997 string btype;
3998 string_init (&btype);
3999 if (demangle_class_name (work, mangled, &btype)) {
4000 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
4001 APPEND_BLANK (result);
4002 string_appends (result, &btype);
4004 else
4005 success = 0;
4006 string_delete (&btype);
4007 break;
4009 case 't':
4011 string btype;
4012 string_init (&btype);
4013 success = demangle_template (work, mangled, &btype, 0, 1, 1);
4014 string_appends (result, &btype);
4015 string_delete (&btype);
4016 break;
4018 default:
4019 success = 0;
4020 break;
4023 return success ? ((int) tk) : 0;
4027 /* Handle a template's value parameter for HP aCC (extension from ARM)
4028 **mangled points to 'S' or 'U' */
4030 static int
4031 do_hpacc_template_const_value (work, mangled, result)
4032 struct work_stuff *work ATTRIBUTE_UNUSED;
4033 const char **mangled;
4034 string *result;
4036 int unsigned_const;
4038 if (**mangled != 'U' && **mangled != 'S')
4039 return 0;
4041 unsigned_const = (**mangled == 'U');
4043 (*mangled)++;
4045 switch (**mangled)
4047 case 'N':
4048 string_append (result, "-");
4049 /* fall through */
4050 case 'P':
4051 (*mangled)++;
4052 break;
4053 case 'M':
4054 /* special case for -2^31 */
4055 string_append (result, "-2147483648");
4056 (*mangled)++;
4057 return 1;
4058 default:
4059 return 0;
4062 /* We have to be looking at an integer now */
4063 if (!(ISDIGIT ((unsigned char)**mangled)))
4064 return 0;
4066 /* We only deal with integral values for template
4067 parameters -- so it's OK to look only for digits */
4068 while (ISDIGIT ((unsigned char)**mangled))
4070 char_str[0] = **mangled;
4071 string_append (result, char_str);
4072 (*mangled)++;
4075 if (unsigned_const)
4076 string_append (result, "U");
4078 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4079 with L or LL suffixes. pai/1997-09-03 */
4081 return 1; /* success */
4084 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4085 **mangled is pointing to the 'A' */
4087 static int
4088 do_hpacc_template_literal (work, mangled, result)
4089 struct work_stuff *work;
4090 const char **mangled;
4091 string *result;
4093 int literal_len = 0;
4094 char * recurse;
4095 char * recurse_dem;
4097 if (**mangled != 'A')
4098 return 0;
4100 (*mangled)++;
4102 literal_len = consume_count (mangled);
4104 if (literal_len <= 0)
4105 return 0;
4107 /* Literal parameters are names of arrays, functions, etc. and the
4108 canonical representation uses the address operator */
4109 string_append (result, "&");
4111 /* Now recursively demangle the literal name */
4112 recurse = (char *) xmalloc (literal_len + 1);
4113 memcpy (recurse, *mangled, literal_len);
4114 recurse[literal_len] = '\000';
4116 recurse_dem = cplus_demangle (recurse, work->options);
4118 if (recurse_dem)
4120 string_append (result, recurse_dem);
4121 free (recurse_dem);
4123 else
4125 string_appendn (result, *mangled, literal_len);
4127 (*mangled) += literal_len;
4128 free (recurse);
4130 return 1;
4133 static int
4134 snarf_numeric_literal (args, arg)
4135 const char ** args;
4136 string * arg;
4138 if (**args == '-')
4140 char_str[0] = '-';
4141 string_append (arg, char_str);
4142 (*args)++;
4144 else if (**args == '+')
4145 (*args)++;
4147 if (!ISDIGIT ((unsigned char)**args))
4148 return 0;
4150 while (ISDIGIT ((unsigned char)**args))
4152 char_str[0] = **args;
4153 string_append (arg, char_str);
4154 (*args)++;
4157 return 1;
4160 /* Demangle the next argument, given by MANGLED into RESULT, which
4161 *should be an uninitialized* string. It will be initialized here,
4162 and free'd should anything go wrong. */
4164 static int
4165 do_arg (work, mangled, result)
4166 struct work_stuff *work;
4167 const char **mangled;
4168 string *result;
4170 /* Remember where we started so that we can record the type, for
4171 non-squangling type remembering. */
4172 const char *start = *mangled;
4174 string_init (result);
4176 if (work->nrepeats > 0)
4178 --work->nrepeats;
4180 if (work->previous_argument == 0)
4181 return 0;
4183 /* We want to reissue the previous type in this argument list. */
4184 string_appends (result, work->previous_argument);
4185 return 1;
4188 if (**mangled == 'n')
4190 /* A squangling-style repeat. */
4191 (*mangled)++;
4192 work->nrepeats = consume_count(mangled);
4194 if (work->nrepeats <= 0)
4195 /* This was not a repeat count after all. */
4196 return 0;
4198 if (work->nrepeats > 9)
4200 if (**mangled != '_')
4201 /* The repeat count should be followed by an '_' in this
4202 case. */
4203 return 0;
4204 else
4205 (*mangled)++;
4208 /* Now, the repeat is all set up. */
4209 return do_arg (work, mangled, result);
4212 /* Save the result in WORK->previous_argument so that we can find it
4213 if it's repeated. Note that saving START is not good enough: we
4214 do not want to add additional types to the back-referenceable
4215 type vector when processing a repeated type. */
4216 if (work->previous_argument)
4217 string_delete (work->previous_argument);
4218 else
4219 work->previous_argument = (string*) xmalloc (sizeof (string));
4221 if (!do_type (work, mangled, work->previous_argument))
4222 return 0;
4224 string_appends (result, work->previous_argument);
4226 remember_type (work, start, *mangled - start);
4227 return 1;
4230 static void
4231 remember_type (work, start, len)
4232 struct work_stuff *work;
4233 const char *start;
4234 int len;
4236 char *tem;
4238 if (work->forgetting_types)
4239 return;
4241 if (work -> ntypes >= work -> typevec_size)
4243 if (work -> typevec_size == 0)
4245 work -> typevec_size = 3;
4246 work -> typevec
4247 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
4249 else
4251 work -> typevec_size *= 2;
4252 work -> typevec
4253 = (char **) xrealloc ((char *)work -> typevec,
4254 sizeof (char *) * work -> typevec_size);
4257 tem = xmalloc (len + 1);
4258 memcpy (tem, start, len);
4259 tem[len] = '\0';
4260 work -> typevec[work -> ntypes++] = tem;
4264 /* Remember a K type class qualifier. */
4265 static void
4266 remember_Ktype (work, start, len)
4267 struct work_stuff *work;
4268 const char *start;
4269 int len;
4271 char *tem;
4273 if (work -> numk >= work -> ksize)
4275 if (work -> ksize == 0)
4277 work -> ksize = 5;
4278 work -> ktypevec
4279 = (char **) xmalloc (sizeof (char *) * work -> ksize);
4281 else
4283 work -> ksize *= 2;
4284 work -> ktypevec
4285 = (char **) xrealloc ((char *)work -> ktypevec,
4286 sizeof (char *) * work -> ksize);
4289 tem = xmalloc (len + 1);
4290 memcpy (tem, start, len);
4291 tem[len] = '\0';
4292 work -> ktypevec[work -> numk++] = tem;
4295 /* Register a B code, and get an index for it. B codes are registered
4296 as they are seen, rather than as they are completed, so map<temp<char> >
4297 registers map<temp<char> > as B0, and temp<char> as B1 */
4299 static int
4300 register_Btype (work)
4301 struct work_stuff *work;
4303 int ret;
4305 if (work -> numb >= work -> bsize)
4307 if (work -> bsize == 0)
4309 work -> bsize = 5;
4310 work -> btypevec
4311 = (char **) xmalloc (sizeof (char *) * work -> bsize);
4313 else
4315 work -> bsize *= 2;
4316 work -> btypevec
4317 = (char **) xrealloc ((char *)work -> btypevec,
4318 sizeof (char *) * work -> bsize);
4321 ret = work -> numb++;
4322 work -> btypevec[ret] = NULL;
4323 return(ret);
4326 /* Store a value into a previously registered B code type. */
4328 static void
4329 remember_Btype (work, start, len, index)
4330 struct work_stuff *work;
4331 const char *start;
4332 int len, index;
4334 char *tem;
4336 tem = xmalloc (len + 1);
4337 memcpy (tem, start, len);
4338 tem[len] = '\0';
4339 work -> btypevec[index] = tem;
4342 /* Lose all the info related to B and K type codes. */
4343 static void
4344 forget_B_and_K_types (work)
4345 struct work_stuff *work;
4347 int i;
4349 while (work -> numk > 0)
4351 i = --(work -> numk);
4352 if (work -> ktypevec[i] != NULL)
4354 free (work -> ktypevec[i]);
4355 work -> ktypevec[i] = NULL;
4359 while (work -> numb > 0)
4361 i = --(work -> numb);
4362 if (work -> btypevec[i] != NULL)
4364 free (work -> btypevec[i]);
4365 work -> btypevec[i] = NULL;
4369 /* Forget the remembered types, but not the type vector itself. */
4371 static void
4372 forget_types (work)
4373 struct work_stuff *work;
4375 int i;
4377 while (work -> ntypes > 0)
4379 i = --(work -> ntypes);
4380 if (work -> typevec[i] != NULL)
4382 free (work -> typevec[i]);
4383 work -> typevec[i] = NULL;
4388 /* Process the argument list part of the signature, after any class spec
4389 has been consumed, as well as the first 'F' character (if any). For
4390 example:
4392 "__als__3fooRT0" => process "RT0"
4393 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4395 DECLP must be already initialised, usually non-empty. It won't be freed
4396 on failure.
4398 Note that g++ differs significantly from ARM and lucid style mangling
4399 with regards to references to previously seen types. For example, given
4400 the source fragment:
4402 class foo {
4403 public:
4404 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4407 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4408 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4410 g++ produces the names:
4412 __3fooiRT0iT2iT2
4413 foo__FiR3fooiT1iT1
4415 while lcc (and presumably other ARM style compilers as well) produces:
4417 foo__FiR3fooT1T2T1T2
4418 __ct__3fooFiR3fooT1T2T1T2
4420 Note that g++ bases its type numbers starting at zero and counts all
4421 previously seen types, while lucid/ARM bases its type numbers starting
4422 at one and only considers types after it has seen the 'F' character
4423 indicating the start of the function args. For lucid/ARM style, we
4424 account for this difference by discarding any previously seen types when
4425 we see the 'F' character, and subtracting one from the type number
4426 reference.
4430 static int
4431 demangle_args (work, mangled, declp)
4432 struct work_stuff *work;
4433 const char **mangled;
4434 string *declp;
4436 string arg;
4437 int need_comma = 0;
4438 int r;
4439 int t;
4440 const char *tem;
4441 char temptype;
4443 if (PRINT_ARG_TYPES)
4445 string_append (declp, "(");
4446 if (**mangled == '\0')
4448 string_append (declp, "void");
4452 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4453 || work->nrepeats > 0)
4455 if ((**mangled == 'N') || (**mangled == 'T'))
4457 temptype = *(*mangled)++;
4459 if (temptype == 'N')
4461 if (!get_count (mangled, &r))
4463 return (0);
4466 else
4468 r = 1;
4470 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4472 /* If we have 10 or more types we might have more than a 1 digit
4473 index so we'll have to consume the whole count here. This
4474 will lose if the next thing is a type name preceded by a
4475 count but it's impossible to demangle that case properly
4476 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4477 Pc, ...)" or "(..., type12, char *, ...)" */
4478 if ((t = consume_count(mangled)) <= 0)
4480 return (0);
4483 else
4485 if (!get_count (mangled, &t))
4487 return (0);
4490 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4492 t--;
4494 /* Validate the type index. Protect against illegal indices from
4495 malformed type strings. */
4496 if ((t < 0) || (t >= work -> ntypes))
4498 return (0);
4500 while (work->nrepeats > 0 || --r >= 0)
4502 tem = work -> typevec[t];
4503 if (need_comma && PRINT_ARG_TYPES)
4505 string_append (declp, ", ");
4507 if (!do_arg (work, &tem, &arg))
4509 return (0);
4511 if (PRINT_ARG_TYPES)
4513 string_appends (declp, &arg);
4515 string_delete (&arg);
4516 need_comma = 1;
4519 else
4521 if (need_comma && PRINT_ARG_TYPES)
4522 string_append (declp, ", ");
4523 if (!do_arg (work, mangled, &arg))
4524 return (0);
4525 if (PRINT_ARG_TYPES)
4526 string_appends (declp, &arg);
4527 string_delete (&arg);
4528 need_comma = 1;
4532 if (**mangled == 'e')
4534 (*mangled)++;
4535 if (PRINT_ARG_TYPES)
4537 if (need_comma)
4539 string_append (declp, ",");
4541 string_append (declp, "...");
4545 if (PRINT_ARG_TYPES)
4547 string_append (declp, ")");
4549 return (1);
4552 /* Like demangle_args, but for demangling the argument lists of function
4553 and method pointers or references, not top-level declarations. */
4555 static int
4556 demangle_nested_args (work, mangled, declp)
4557 struct work_stuff *work;
4558 const char **mangled;
4559 string *declp;
4561 string* saved_previous_argument;
4562 int result;
4563 int saved_nrepeats;
4565 /* The G++ name-mangling algorithm does not remember types on nested
4566 argument lists, unless -fsquangling is used, and in that case the
4567 type vector updated by remember_type is not used. So, we turn
4568 off remembering of types here. */
4569 ++work->forgetting_types;
4571 /* For the repeat codes used with -fsquangling, we must keep track of
4572 the last argument. */
4573 saved_previous_argument = work->previous_argument;
4574 saved_nrepeats = work->nrepeats;
4575 work->previous_argument = 0;
4576 work->nrepeats = 0;
4578 /* Actually demangle the arguments. */
4579 result = demangle_args (work, mangled, declp);
4581 /* Restore the previous_argument field. */
4582 if (work->previous_argument)
4584 string_delete (work->previous_argument);
4585 free ((char *) work->previous_argument);
4587 work->previous_argument = saved_previous_argument;
4588 --work->forgetting_types;
4589 work->nrepeats = saved_nrepeats;
4591 return result;
4594 static void
4595 demangle_function_name (work, mangled, declp, scan)
4596 struct work_stuff *work;
4597 const char **mangled;
4598 string *declp;
4599 const char *scan;
4601 size_t i;
4602 string type;
4603 const char *tem;
4605 string_appendn (declp, (*mangled), scan - (*mangled));
4606 string_need (declp, 1);
4607 *(declp -> p) = '\0';
4609 /* Consume the function name, including the "__" separating the name
4610 from the signature. We are guaranteed that SCAN points to the
4611 separator. */
4613 (*mangled) = scan + 2;
4614 /* We may be looking at an instantiation of a template function:
4615 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4616 following _F marks the start of the function arguments. Handle
4617 the template arguments first. */
4619 if (HP_DEMANGLING && (**mangled == 'X'))
4621 demangle_arm_hp_template (work, mangled, 0, declp);
4622 /* This leaves MANGLED pointing to the 'F' marking func args */
4625 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4628 /* See if we have an ARM style constructor or destructor operator.
4629 If so, then just record it, clear the decl, and return.
4630 We can't build the actual constructor/destructor decl until later,
4631 when we recover the class name from the signature. */
4633 if (strcmp (declp -> b, "__ct") == 0)
4635 work -> constructor += 1;
4636 string_clear (declp);
4637 return;
4639 else if (strcmp (declp -> b, "__dt") == 0)
4641 work -> destructor += 1;
4642 string_clear (declp);
4643 return;
4647 if (declp->p - declp->b >= 3
4648 && declp->b[0] == 'o'
4649 && declp->b[1] == 'p'
4650 && strchr (cplus_markers, declp->b[2]) != NULL)
4652 /* see if it's an assignment expression */
4653 if (declp->p - declp->b >= 10 /* op$assign_ */
4654 && memcmp (declp->b + 3, "assign_", 7) == 0)
4656 for (i = 0; i < ARRAY_SIZE (optable); i++)
4658 int len = declp->p - declp->b - 10;
4659 if ((int) strlen (optable[i].in) == len
4660 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4662 string_clear (declp);
4663 string_append (declp, "operator");
4664 string_append (declp, optable[i].out);
4665 string_append (declp, "=");
4666 break;
4670 else
4672 for (i = 0; i < ARRAY_SIZE (optable); i++)
4674 int len = declp->p - declp->b - 3;
4675 if ((int) strlen (optable[i].in) == len
4676 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4678 string_clear (declp);
4679 string_append (declp, "operator");
4680 string_append (declp, optable[i].out);
4681 break;
4686 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4687 && strchr (cplus_markers, declp->b[4]) != NULL)
4689 /* type conversion operator */
4690 tem = declp->b + 5;
4691 if (do_type (work, &tem, &type))
4693 string_clear (declp);
4694 string_append (declp, "operator ");
4695 string_appends (declp, &type);
4696 string_delete (&type);
4699 else if (declp->b[0] == '_' && declp->b[1] == '_'
4700 && declp->b[2] == 'o' && declp->b[3] == 'p')
4702 /* ANSI. */
4703 /* type conversion operator. */
4704 tem = declp->b + 4;
4705 if (do_type (work, &tem, &type))
4707 string_clear (declp);
4708 string_append (declp, "operator ");
4709 string_appends (declp, &type);
4710 string_delete (&type);
4713 else if (declp->b[0] == '_' && declp->b[1] == '_'
4714 && ISLOWER((unsigned char)declp->b[2])
4715 && ISLOWER((unsigned char)declp->b[3]))
4717 if (declp->b[4] == '\0')
4719 /* Operator. */
4720 for (i = 0; i < ARRAY_SIZE (optable); i++)
4722 if (strlen (optable[i].in) == 2
4723 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4725 string_clear (declp);
4726 string_append (declp, "operator");
4727 string_append (declp, optable[i].out);
4728 break;
4732 else
4734 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4736 /* Assignment. */
4737 for (i = 0; i < ARRAY_SIZE (optable); i++)
4739 if (strlen (optable[i].in) == 3
4740 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4742 string_clear (declp);
4743 string_append (declp, "operator");
4744 string_append (declp, optable[i].out);
4745 break;
4753 /* a mini string-handling package */
4755 static void
4756 string_need (s, n)
4757 string *s;
4758 int n;
4760 int tem;
4762 if (s->b == NULL)
4764 if (n < 32)
4766 n = 32;
4768 s->p = s->b = xmalloc (n);
4769 s->e = s->b + n;
4771 else if (s->e - s->p < n)
4773 tem = s->p - s->b;
4774 n += tem;
4775 n *= 2;
4776 s->b = xrealloc (s->b, n);
4777 s->p = s->b + tem;
4778 s->e = s->b + n;
4782 static void
4783 string_delete (s)
4784 string *s;
4786 if (s->b != NULL)
4788 free (s->b);
4789 s->b = s->e = s->p = NULL;
4793 static void
4794 string_init (s)
4795 string *s;
4797 s->b = s->p = s->e = NULL;
4800 static void
4801 string_clear (s)
4802 string *s;
4804 s->p = s->b;
4807 #if 0
4809 static int
4810 string_empty (s)
4811 string *s;
4813 return (s->b == s->p);
4816 #endif
4818 static void
4819 string_append (p, s)
4820 string *p;
4821 const char *s;
4823 int n;
4824 if (s == NULL || *s == '\0')
4825 return;
4826 n = strlen (s);
4827 string_need (p, n);
4828 memcpy (p->p, s, n);
4829 p->p += n;
4832 static void
4833 string_appends (p, s)
4834 string *p, *s;
4836 int n;
4838 if (s->b != s->p)
4840 n = s->p - s->b;
4841 string_need (p, n);
4842 memcpy (p->p, s->b, n);
4843 p->p += n;
4847 static void
4848 string_appendn (p, s, n)
4849 string *p;
4850 const char *s;
4851 int n;
4853 if (n != 0)
4855 string_need (p, n);
4856 memcpy (p->p, s, n);
4857 p->p += n;
4861 static void
4862 string_prepend (p, s)
4863 string *p;
4864 const char *s;
4866 if (s != NULL && *s != '\0')
4868 string_prependn (p, s, strlen (s));
4872 static void
4873 string_prepends (p, s)
4874 string *p, *s;
4876 if (s->b != s->p)
4878 string_prependn (p, s->b, s->p - s->b);
4882 static void
4883 string_prependn (p, s, n)
4884 string *p;
4885 const char *s;
4886 int n;
4888 char *q;
4890 if (n != 0)
4892 string_need (p, n);
4893 for (q = p->p - 1; q >= p->b; q--)
4895 q[n] = q[0];
4897 memcpy (p->b, s, n);
4898 p->p += n;
4902 static void
4903 string_append_template_idx (s, idx)
4904 string *s;
4905 int idx;
4907 char buf[INTBUF_SIZE + 1 /* 'T' */];
4908 sprintf(buf, "T%d", idx);
4909 string_append (s, buf);