]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - libiberty/cplus-dem.c
libiberty: Add Rust symbol demangling.
[thirdparty/binutils-gdb.git] / libiberty / cplus-dem.c
1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2010 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
7
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.
13
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.)
22
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.
27
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., 51 Franklin Street - Fifth Floor,
31 Boston, MA 02110-1301, USA. */
32
33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
34
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. */
38
39 /* This file lives in both GCC and libiberty. When making changes, please
40 try not to break either. */
41
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
45
46 #include "safe-ctype.h"
47
48 #include <sys/types.h>
49 #include <string.h>
50 #include <stdio.h>
51
52 #ifdef HAVE_STDLIB_H
53 #include <stdlib.h>
54 #else
55 void * malloc ();
56 void * realloc ();
57 #endif
58
59 #ifdef HAVE_LIMITS_H
60 #include <limits.h>
61 #endif
62 #ifndef INT_MAX
63 # define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */
64 #endif
65
66 #include <demangle.h>
67 #undef CURRENT_DEMANGLING_STYLE
68 #define CURRENT_DEMANGLING_STYLE work->options
69
70 #include "libiberty.h"
71
72 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
73
74 /* A value at least one greater than the maximum number of characters
75 that will be output when using the `%d' format with `printf'. */
76 #define INTBUF_SIZE 32
77
78 extern void fancy_abort (void) ATTRIBUTE_NORETURN;
79
80 /* In order to allow a single demangler executable to demangle strings
81 using various common values of CPLUS_MARKER, as well as any specific
82 one set at compile time, we maintain a string containing all the
83 commonly used ones, and check to see if the marker we are looking for
84 is in that string. CPLUS_MARKER is usually '$' on systems where the
85 assembler can deal with that. Where the assembler can't, it's usually
86 '.' (but on many systems '.' is used for other things). We put the
87 current defined CPLUS_MARKER first (which defaults to '$'), followed
88 by the next most common value, followed by an explicit '$' in case
89 the value of CPLUS_MARKER is not '$'.
90
91 We could avoid this if we could just get g++ to tell us what the actual
92 cplus marker character is as part of the debug information, perhaps by
93 ensuring that it is the character that terminates the gcc<n>_compiled
94 marker symbol (FIXME). */
95
96 #if !defined (CPLUS_MARKER)
97 #define CPLUS_MARKER '$'
98 #endif
99
100 enum demangling_styles current_demangling_style = auto_demangling;
101
102 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
103
104 static char char_str[2] = { '\000', '\000' };
105
106 void
107 set_cplus_marker_for_demangling (int ch)
108 {
109 cplus_markers[0] = ch;
110 }
111
112 typedef struct string /* Beware: these aren't required to be */
113 { /* '\0' terminated. */
114 char *b; /* pointer to start of string */
115 char *p; /* pointer after last character */
116 char *e; /* pointer after end of allocated space */
117 } string;
118
119 /* Stuff that is shared between sub-routines.
120 Using a shared structure allows cplus_demangle to be reentrant. */
121
122 struct work_stuff
123 {
124 int options;
125 char **typevec;
126 char **ktypevec;
127 char **btypevec;
128 int numk;
129 int numb;
130 int ksize;
131 int bsize;
132 int ntypes;
133 int typevec_size;
134 int constructor;
135 int destructor;
136 int static_type; /* A static member function */
137 int temp_start; /* index in demangled to start of template args */
138 int type_quals; /* The type qualifiers. */
139 int dllimported; /* Symbol imported from a PE DLL */
140 char **tmpl_argvec; /* Template function arguments. */
141 int ntmpl_args; /* The number of template function arguments. */
142 int forgetting_types; /* Nonzero if we are not remembering the types
143 we see. */
144 string* previous_argument; /* The last function argument demangled. */
145 int nrepeats; /* The number of times to repeat the previous
146 argument. */
147 int *proctypevec; /* Indices of currently processed remembered typevecs. */
148 int proctypevec_size;
149 int nproctypes;
150 };
151
152 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
153 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
154
155 static const struct optable
156 {
157 const char *const in;
158 const char *const out;
159 const int flags;
160 } optable[] = {
161 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
162 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
163 {"new", " new", 0}, /* old (1.91, and 1.x) */
164 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
165 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
166 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
167 {"as", "=", DMGL_ANSI}, /* ansi */
168 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
169 {"eq", "==", DMGL_ANSI}, /* old, ansi */
170 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
171 {"gt", ">", DMGL_ANSI}, /* old, ansi */
172 {"le", "<=", DMGL_ANSI}, /* old, ansi */
173 {"lt", "<", DMGL_ANSI}, /* old, ansi */
174 {"plus", "+", 0}, /* old */
175 {"pl", "+", DMGL_ANSI}, /* ansi */
176 {"apl", "+=", DMGL_ANSI}, /* ansi */
177 {"minus", "-", 0}, /* old */
178 {"mi", "-", DMGL_ANSI}, /* ansi */
179 {"ami", "-=", DMGL_ANSI}, /* ansi */
180 {"mult", "*", 0}, /* old */
181 {"ml", "*", DMGL_ANSI}, /* ansi */
182 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
183 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
184 {"convert", "+", 0}, /* old (unary +) */
185 {"negate", "-", 0}, /* old (unary -) */
186 {"trunc_mod", "%", 0}, /* old */
187 {"md", "%", DMGL_ANSI}, /* ansi */
188 {"amd", "%=", DMGL_ANSI}, /* ansi */
189 {"trunc_div", "/", 0}, /* old */
190 {"dv", "/", DMGL_ANSI}, /* ansi */
191 {"adv", "/=", DMGL_ANSI}, /* ansi */
192 {"truth_andif", "&&", 0}, /* old */
193 {"aa", "&&", DMGL_ANSI}, /* ansi */
194 {"truth_orif", "||", 0}, /* old */
195 {"oo", "||", DMGL_ANSI}, /* ansi */
196 {"truth_not", "!", 0}, /* old */
197 {"nt", "!", DMGL_ANSI}, /* ansi */
198 {"postincrement","++", 0}, /* old */
199 {"pp", "++", DMGL_ANSI}, /* ansi */
200 {"postdecrement","--", 0}, /* old */
201 {"mm", "--", DMGL_ANSI}, /* ansi */
202 {"bit_ior", "|", 0}, /* old */
203 {"or", "|", DMGL_ANSI}, /* ansi */
204 {"aor", "|=", DMGL_ANSI}, /* ansi */
205 {"bit_xor", "^", 0}, /* old */
206 {"er", "^", DMGL_ANSI}, /* ansi */
207 {"aer", "^=", DMGL_ANSI}, /* ansi */
208 {"bit_and", "&", 0}, /* old */
209 {"ad", "&", DMGL_ANSI}, /* ansi */
210 {"aad", "&=", DMGL_ANSI}, /* ansi */
211 {"bit_not", "~", 0}, /* old */
212 {"co", "~", DMGL_ANSI}, /* ansi */
213 {"call", "()", 0}, /* old */
214 {"cl", "()", DMGL_ANSI}, /* ansi */
215 {"alshift", "<<", 0}, /* old */
216 {"ls", "<<", DMGL_ANSI}, /* ansi */
217 {"als", "<<=", DMGL_ANSI}, /* ansi */
218 {"arshift", ">>", 0}, /* old */
219 {"rs", ">>", DMGL_ANSI}, /* ansi */
220 {"ars", ">>=", DMGL_ANSI}, /* ansi */
221 {"component", "->", 0}, /* old */
222 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
223 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
224 {"indirect", "*", 0}, /* old */
225 {"method_call", "->()", 0}, /* old */
226 {"addr", "&", 0}, /* old (unary &) */
227 {"array", "[]", 0}, /* old */
228 {"vc", "[]", DMGL_ANSI}, /* ansi */
229 {"compound", ", ", 0}, /* old */
230 {"cm", ", ", DMGL_ANSI}, /* ansi */
231 {"cond", "?:", 0}, /* old */
232 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
233 {"max", ">?", 0}, /* old */
234 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
235 {"min", "<?", 0}, /* old */
236 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
237 {"nop", "", 0}, /* old (for operator=) */
238 {"rm", "->*", DMGL_ANSI}, /* ansi */
239 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
240 };
241
242 /* These values are used to indicate the various type varieties.
243 They are all non-zero so that they can be used as `success'
244 values. */
245 typedef enum type_kind_t
246 {
247 tk_none,
248 tk_pointer,
249 tk_reference,
250 tk_rvalue_reference,
251 tk_integral,
252 tk_bool,
253 tk_char,
254 tk_real
255 } type_kind_t;
256
257 const struct demangler_engine libiberty_demanglers[] =
258 {
259 {
260 NO_DEMANGLING_STYLE_STRING,
261 no_demangling,
262 "Demangling disabled"
263 }
264 ,
265 {
266 AUTO_DEMANGLING_STYLE_STRING,
267 auto_demangling,
268 "Automatic selection based on executable"
269 }
270 ,
271 {
272 GNU_DEMANGLING_STYLE_STRING,
273 gnu_demangling,
274 "GNU (g++) style demangling"
275 }
276 ,
277 {
278 LUCID_DEMANGLING_STYLE_STRING,
279 lucid_demangling,
280 "Lucid (lcc) style demangling"
281 }
282 ,
283 {
284 ARM_DEMANGLING_STYLE_STRING,
285 arm_demangling,
286 "ARM style demangling"
287 }
288 ,
289 {
290 HP_DEMANGLING_STYLE_STRING,
291 hp_demangling,
292 "HP (aCC) style demangling"
293 }
294 ,
295 {
296 EDG_DEMANGLING_STYLE_STRING,
297 edg_demangling,
298 "EDG style demangling"
299 }
300 ,
301 {
302 GNU_V3_DEMANGLING_STYLE_STRING,
303 gnu_v3_demangling,
304 "GNU (g++) V3 ABI-style demangling"
305 }
306 ,
307 {
308 JAVA_DEMANGLING_STYLE_STRING,
309 java_demangling,
310 "Java style demangling"
311 }
312 ,
313 {
314 GNAT_DEMANGLING_STYLE_STRING,
315 gnat_demangling,
316 "GNAT style demangling"
317 }
318 ,
319 {
320 DLANG_DEMANGLING_STYLE_STRING,
321 dlang_demangling,
322 "DLANG style demangling"
323 }
324 ,
325 {
326 RUST_DEMANGLING_STYLE_STRING,
327 rust_demangling,
328 "Rust style demangling"
329 }
330 ,
331 {
332 NULL, unknown_demangling, NULL
333 }
334 };
335
336 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
337 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
338 string_append(str, " ");}
339 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
340
341 /* The scope separator appropriate for the language being demangled. */
342
343 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
344
345 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
346 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
347
348 /* Prototypes for local functions */
349
350 static void delete_work_stuff (struct work_stuff *);
351
352 static void delete_non_B_K_work_stuff (struct work_stuff *);
353
354 static char *mop_up (struct work_stuff *, string *, int);
355
356 static void squangle_mop_up (struct work_stuff *);
357
358 static void work_stuff_copy_to_from (struct work_stuff *, struct work_stuff *);
359
360 #if 0
361 static int
362 demangle_method_args (struct work_stuff *, const char **, string *);
363 #endif
364
365 static char *
366 internal_cplus_demangle (struct work_stuff *, const char *);
367
368 static int
369 demangle_template_template_parm (struct work_stuff *work,
370 const char **, string *);
371
372 static int
373 demangle_template (struct work_stuff *work, const char **, string *,
374 string *, int, int);
375
376 static int
377 arm_pt (struct work_stuff *, const char *, int, const char **,
378 const char **);
379
380 static int
381 demangle_class_name (struct work_stuff *, const char **, string *);
382
383 static int
384 demangle_qualified (struct work_stuff *, const char **, string *,
385 int, int);
386
387 static int demangle_class (struct work_stuff *, const char **, string *);
388
389 static int demangle_fund_type (struct work_stuff *, const char **, string *);
390
391 static int demangle_signature (struct work_stuff *, const char **, string *);
392
393 static int demangle_prefix (struct work_stuff *, const char **, string *);
394
395 static int gnu_special (struct work_stuff *, const char **, string *);
396
397 static int arm_special (const char **, string *);
398
399 static void string_need (string *, int);
400
401 static void string_delete (string *);
402
403 static void
404 string_init (string *);
405
406 static void string_clear (string *);
407
408 #if 0
409 static int string_empty (string *);
410 #endif
411
412 static void string_append (string *, const char *);
413
414 static void string_appends (string *, string *);
415
416 static void string_appendn (string *, const char *, int);
417
418 static void string_prepend (string *, const char *);
419
420 static void string_prependn (string *, const char *, int);
421
422 static void string_append_template_idx (string *, int);
423
424 static int get_count (const char **, int *);
425
426 static int consume_count (const char **);
427
428 static int consume_count_with_underscores (const char**);
429
430 static int demangle_args (struct work_stuff *, const char **, string *);
431
432 static int demangle_nested_args (struct work_stuff*, const char**, string*);
433
434 static int do_type (struct work_stuff *, const char **, string *);
435
436 static int do_arg (struct work_stuff *, const char **, string *);
437
438 static int
439 demangle_function_name (struct work_stuff *, const char **, string *,
440 const char *);
441
442 static int
443 iterate_demangle_function (struct work_stuff *,
444 const char **, string *, const char *);
445
446 static void remember_type (struct work_stuff *, const char *, int);
447
448 static void push_processed_type (struct work_stuff *, int);
449
450 static void pop_processed_type (struct work_stuff *);
451
452 static void remember_Btype (struct work_stuff *, const char *, int, int);
453
454 static int register_Btype (struct work_stuff *);
455
456 static void remember_Ktype (struct work_stuff *, const char *, int);
457
458 static void forget_types (struct work_stuff *);
459
460 static void forget_B_and_K_types (struct work_stuff *);
461
462 static void string_prepends (string *, string *);
463
464 static int
465 demangle_template_value_parm (struct work_stuff*, const char**,
466 string*, type_kind_t);
467
468 static int
469 do_hpacc_template_const_value (struct work_stuff *, const char **, string *);
470
471 static int
472 do_hpacc_template_literal (struct work_stuff *, const char **, string *);
473
474 static int snarf_numeric_literal (const char **, string *);
475
476 /* There is a TYPE_QUAL value for each type qualifier. They can be
477 combined by bitwise-or to form the complete set of qualifiers for a
478 type. */
479
480 #define TYPE_UNQUALIFIED 0x0
481 #define TYPE_QUAL_CONST 0x1
482 #define TYPE_QUAL_VOLATILE 0x2
483 #define TYPE_QUAL_RESTRICT 0x4
484
485 static int code_for_qualifier (int);
486
487 static const char* qualifier_string (int);
488
489 static const char* demangle_qualifier (int);
490
491 static int demangle_expression (struct work_stuff *, const char **, string *,
492 type_kind_t);
493
494 static int
495 demangle_integral_value (struct work_stuff *, const char **, string *);
496
497 static int
498 demangle_real_value (struct work_stuff *, const char **, string *);
499
500 static void
501 demangle_arm_hp_template (struct work_stuff *, const char **, int, string *);
502
503 static void
504 recursively_demangle (struct work_stuff *, const char **, string *, int);
505
506 /* Translate count to integer, consuming tokens in the process.
507 Conversion terminates on the first non-digit character.
508
509 Trying to consume something that isn't a count results in no
510 consumption of input and a return of -1.
511
512 Overflow consumes the rest of the digits, and returns -1. */
513
514 static int
515 consume_count (const char **type)
516 {
517 int count = 0;
518
519 if (! ISDIGIT ((unsigned char)**type))
520 return -1;
521
522 while (ISDIGIT ((unsigned char)**type))
523 {
524 count *= 10;
525
526 /* Check for overflow.
527 We assume that count is represented using two's-complement;
528 no power of two is divisible by ten, so if an overflow occurs
529 when multiplying by ten, the result will not be a multiple of
530 ten. */
531 if ((count % 10) != 0)
532 {
533 while (ISDIGIT ((unsigned char) **type))
534 (*type)++;
535 return -1;
536 }
537
538 count += **type - '0';
539 (*type)++;
540 }
541
542 if (count < 0)
543 count = -1;
544
545 return (count);
546 }
547
548
549 /* Like consume_count, but for counts that are preceded and followed
550 by '_' if they are greater than 10. Also, -1 is returned for
551 failure, since 0 can be a valid value. */
552
553 static int
554 consume_count_with_underscores (const char **mangled)
555 {
556 int idx;
557
558 if (**mangled == '_')
559 {
560 (*mangled)++;
561 if (!ISDIGIT ((unsigned char)**mangled))
562 return -1;
563
564 idx = consume_count (mangled);
565 if (**mangled != '_')
566 /* The trailing underscore was missing. */
567 return -1;
568
569 (*mangled)++;
570 }
571 else
572 {
573 if (**mangled < '0' || **mangled > '9')
574 return -1;
575
576 idx = **mangled - '0';
577 (*mangled)++;
578 }
579
580 return idx;
581 }
582
583 /* C is the code for a type-qualifier. Return the TYPE_QUAL
584 corresponding to this qualifier. */
585
586 static int
587 code_for_qualifier (int c)
588 {
589 switch (c)
590 {
591 case 'C':
592 return TYPE_QUAL_CONST;
593
594 case 'V':
595 return TYPE_QUAL_VOLATILE;
596
597 case 'u':
598 return TYPE_QUAL_RESTRICT;
599
600 default:
601 break;
602 }
603
604 /* C was an invalid qualifier. */
605 abort ();
606 }
607
608 /* Return the string corresponding to the qualifiers given by
609 TYPE_QUALS. */
610
611 static const char*
612 qualifier_string (int type_quals)
613 {
614 switch (type_quals)
615 {
616 case TYPE_UNQUALIFIED:
617 return "";
618
619 case TYPE_QUAL_CONST:
620 return "const";
621
622 case TYPE_QUAL_VOLATILE:
623 return "volatile";
624
625 case TYPE_QUAL_RESTRICT:
626 return "__restrict";
627
628 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
629 return "const volatile";
630
631 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
632 return "const __restrict";
633
634 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
635 return "volatile __restrict";
636
637 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
638 return "const volatile __restrict";
639
640 default:
641 break;
642 }
643
644 /* TYPE_QUALS was an invalid qualifier set. */
645 abort ();
646 }
647
648 /* C is the code for a type-qualifier. Return the string
649 corresponding to this qualifier. This function should only be
650 called with a valid qualifier code. */
651
652 static const char*
653 demangle_qualifier (int c)
654 {
655 return qualifier_string (code_for_qualifier (c));
656 }
657
658 int
659 cplus_demangle_opname (const char *opname, char *result, int options)
660 {
661 int len, len1, ret;
662 string type;
663 struct work_stuff work[1];
664 const char *tem;
665
666 len = strlen(opname);
667 result[0] = '\0';
668 ret = 0;
669 memset ((char *) work, 0, sizeof (work));
670 work->options = options;
671
672 if (opname[0] == '_' && opname[1] == '_'
673 && opname[2] == 'o' && opname[3] == 'p')
674 {
675 /* ANSI. */
676 /* type conversion operator. */
677 tem = opname + 4;
678 if (do_type (work, &tem, &type))
679 {
680 strcat (result, "operator ");
681 strncat (result, type.b, type.p - type.b);
682 string_delete (&type);
683 ret = 1;
684 }
685 }
686 else if (opname[0] == '_' && opname[1] == '_'
687 && ISLOWER((unsigned char)opname[2])
688 && ISLOWER((unsigned char)opname[3]))
689 {
690 if (opname[4] == '\0')
691 {
692 /* Operator. */
693 size_t i;
694 for (i = 0; i < ARRAY_SIZE (optable); i++)
695 {
696 if (strlen (optable[i].in) == 2
697 && memcmp (optable[i].in, opname + 2, 2) == 0)
698 {
699 strcat (result, "operator");
700 strcat (result, optable[i].out);
701 ret = 1;
702 break;
703 }
704 }
705 }
706 else
707 {
708 if (opname[2] == 'a' && opname[5] == '\0')
709 {
710 /* Assignment. */
711 size_t i;
712 for (i = 0; i < ARRAY_SIZE (optable); i++)
713 {
714 if (strlen (optable[i].in) == 3
715 && memcmp (optable[i].in, opname + 2, 3) == 0)
716 {
717 strcat (result, "operator");
718 strcat (result, optable[i].out);
719 ret = 1;
720 break;
721 }
722 }
723 }
724 }
725 }
726 else if (len >= 3
727 && opname[0] == 'o'
728 && opname[1] == 'p'
729 && strchr (cplus_markers, opname[2]) != NULL)
730 {
731 /* see if it's an assignment expression */
732 if (len >= 10 /* op$assign_ */
733 && memcmp (opname + 3, "assign_", 7) == 0)
734 {
735 size_t i;
736 for (i = 0; i < ARRAY_SIZE (optable); i++)
737 {
738 len1 = len - 10;
739 if ((int) strlen (optable[i].in) == len1
740 && memcmp (optable[i].in, opname + 10, len1) == 0)
741 {
742 strcat (result, "operator");
743 strcat (result, optable[i].out);
744 strcat (result, "=");
745 ret = 1;
746 break;
747 }
748 }
749 }
750 else
751 {
752 size_t i;
753 for (i = 0; i < ARRAY_SIZE (optable); i++)
754 {
755 len1 = len - 3;
756 if ((int) strlen (optable[i].in) == len1
757 && memcmp (optable[i].in, opname + 3, len1) == 0)
758 {
759 strcat (result, "operator");
760 strcat (result, optable[i].out);
761 ret = 1;
762 break;
763 }
764 }
765 }
766 }
767 else if (len >= 5 && memcmp (opname, "type", 4) == 0
768 && strchr (cplus_markers, opname[4]) != NULL)
769 {
770 /* type conversion operator */
771 tem = opname + 5;
772 if (do_type (work, &tem, &type))
773 {
774 strcat (result, "operator ");
775 strncat (result, type.b, type.p - type.b);
776 string_delete (&type);
777 ret = 1;
778 }
779 }
780 squangle_mop_up (work);
781 return ret;
782
783 }
784
785 /* Takes operator name as e.g. "++" and returns mangled
786 operator name (e.g. "postincrement_expr"), or NULL if not found.
787
788 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
789 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
790
791 const char *
792 cplus_mangle_opname (const char *opname, int options)
793 {
794 size_t i;
795 int len;
796
797 len = strlen (opname);
798 for (i = 0; i < ARRAY_SIZE (optable); i++)
799 {
800 if ((int) strlen (optable[i].out) == len
801 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
802 && memcmp (optable[i].out, opname, len) == 0)
803 return optable[i].in;
804 }
805 return (0);
806 }
807
808 /* Add a routine to set the demangling style to be sure it is valid and
809 allow for any demangler initialization that maybe necessary. */
810
811 enum demangling_styles
812 cplus_demangle_set_style (enum demangling_styles style)
813 {
814 const struct demangler_engine *demangler = libiberty_demanglers;
815
816 for (; demangler->demangling_style != unknown_demangling; ++demangler)
817 if (style == demangler->demangling_style)
818 {
819 current_demangling_style = style;
820 return current_demangling_style;
821 }
822
823 return unknown_demangling;
824 }
825
826 /* Do string name to style translation */
827
828 enum demangling_styles
829 cplus_demangle_name_to_style (const char *name)
830 {
831 const struct demangler_engine *demangler = libiberty_demanglers;
832
833 for (; demangler->demangling_style != unknown_demangling; ++demangler)
834 if (strcmp (name, demangler->demangling_style_name) == 0)
835 return demangler->demangling_style;
836
837 return unknown_demangling;
838 }
839
840 /* char *cplus_demangle (const char *mangled, int options)
841
842 If MANGLED is a mangled function name produced by GNU C++, then
843 a pointer to a @code{malloc}ed string giving a C++ representation
844 of the name will be returned; otherwise NULL will be returned.
845 It is the caller's responsibility to free the string which
846 is returned.
847
848 The OPTIONS arg may contain one or more of the following bits:
849
850 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
851 included.
852 DMGL_PARAMS Function parameters are included.
853
854 For example,
855
856 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
857 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
858 cplus_demangle ("foo__1Ai", 0) => "A::foo"
859
860 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
861 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
862 cplus_demangle ("foo__1Afe", 0) => "A::foo"
863
864 Note that any leading underscores, or other such characters prepended by
865 the compilation system, are presumed to have already been stripped from
866 MANGLED. */
867
868 char *
869 cplus_demangle (const char *mangled, int options)
870 {
871 char *ret;
872 struct work_stuff work[1];
873
874 if (current_demangling_style == no_demangling)
875 return xstrdup (mangled);
876
877 memset ((char *) work, 0, sizeof (work));
878 work->options = options;
879 if ((work->options & DMGL_STYLE_MASK) == 0)
880 work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
881
882 /* The V3 ABI demangling is implemented elsewhere. */
883 if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING)
884 {
885 ret = cplus_demangle_v3 (mangled, work->options);
886 if (GNU_V3_DEMANGLING)
887 return ret;
888
889 if (ret)
890 {
891 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions.
892 The subtitutions are always smaller, so do in place changes. */
893 if (rust_is_mangled (ret))
894 rust_demangle_sym (ret);
895 else if (RUST_DEMANGLING)
896 {
897 free (ret);
898 ret = NULL;
899 }
900 }
901
902 if (ret || RUST_DEMANGLING)
903 return ret;
904 }
905
906 if (JAVA_DEMANGLING)
907 {
908 ret = java_demangle_v3 (mangled);
909 if (ret)
910 return ret;
911 }
912
913 if (GNAT_DEMANGLING)
914 return ada_demangle (mangled, options);
915
916 if (DLANG_DEMANGLING)
917 {
918 ret = dlang_demangle (mangled, options);
919 if (ret)
920 return ret;
921 }
922
923 ret = internal_cplus_demangle (work, mangled);
924 squangle_mop_up (work);
925 return (ret);
926 }
927
928 char *
929 rust_demangle (const char *mangled, int options)
930 {
931 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions. */
932 char *ret = cplus_demangle_v3 (mangled, options);
933
934 /* The Rust subtitutions are always smaller, so do in place changes. */
935 if (ret != NULL)
936 {
937 if (rust_is_mangled (ret))
938 rust_demangle_sym (ret);
939 else
940 {
941 free (ret);
942 ret = NULL;
943 }
944 }
945
946 return ret;
947 }
948
949 /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
950
951 char *
952 ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
953 {
954 int len0;
955 const char* p;
956 char *d;
957 char *demangled = NULL;
958
959 /* Discard leading _ada_, which is used for library level subprograms. */
960 if (strncmp (mangled, "_ada_", 5) == 0)
961 mangled += 5;
962
963 /* All ada unit names are lower-case. */
964 if (!ISLOWER (mangled[0]))
965 goto unknown;
966
967 /* Most of the demangling will trivially remove chars. Operator names
968 may add one char but because they are always preceeded by '__' which is
969 replaced by '.', they eventually never expand the size.
970 A few special names such as '___elabs' add a few chars (at most 7), but
971 they occur only once. */
972 len0 = strlen (mangled) + 7 + 1;
973 demangled = XNEWVEC (char, len0);
974
975 d = demangled;
976 p = mangled;
977 while (1)
978 {
979 /* An entity names is expected. */
980 if (ISLOWER (*p))
981 {
982 /* An identifier, which is always lower case. */
983 do
984 *d++ = *p++;
985 while (ISLOWER(*p) || ISDIGIT (*p)
986 || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
987 }
988 else if (p[0] == 'O')
989 {
990 /* An operator name. */
991 static const char * const operators[][2] =
992 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
993 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
994 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
995 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
996 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
997 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
998 {"Oexpon", "**"}, {NULL, NULL}};
999 int k;
1000
1001 for (k = 0; operators[k][0] != NULL; k++)
1002 {
1003 size_t slen = strlen (operators[k][0]);
1004 if (strncmp (p, operators[k][0], slen) == 0)
1005 {
1006 p += slen;
1007 slen = strlen (operators[k][1]);
1008 *d++ = '"';
1009 memcpy (d, operators[k][1], slen);
1010 d += slen;
1011 *d++ = '"';
1012 break;
1013 }
1014 }
1015 /* Operator not found. */
1016 if (operators[k][0] == NULL)
1017 goto unknown;
1018 }
1019 else
1020 {
1021 /* Not a GNAT encoding. */
1022 goto unknown;
1023 }
1024
1025 /* The name can be directly followed by some uppercase letters. */
1026 if (p[0] == 'T' && p[1] == 'K')
1027 {
1028 /* Task stuff. */
1029 if (p[2] == 'B' && p[3] == 0)
1030 {
1031 /* Subprogram for task body. */
1032 break;
1033 }
1034 else if (p[2] == '_' && p[3] == '_')
1035 {
1036 /* Inner declarations in a task. */
1037 p += 4;
1038 *d++ = '.';
1039 continue;
1040 }
1041 else
1042 goto unknown;
1043 }
1044 if (p[0] == 'E' && p[1] == 0)
1045 {
1046 /* Exception name. */
1047 goto unknown;
1048 }
1049 if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
1050 {
1051 /* Protected type subprogram. */
1052 break;
1053 }
1054 if ((*p == 'N' || *p == 'S') && p[1] == 0)
1055 {
1056 /* Enumerated type name table. */
1057 goto unknown;
1058 }
1059 if (p[0] == 'X')
1060 {
1061 /* Body nested. */
1062 p++;
1063 while (p[0] == 'n' || p[0] == 'b')
1064 p++;
1065 }
1066 if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
1067 {
1068 /* Stream operations. */
1069 const char *name;
1070 switch (p[1])
1071 {
1072 case 'R':
1073 name = "'Read";
1074 break;
1075 case 'W':
1076 name = "'Write";
1077 break;
1078 case 'I':
1079 name = "'Input";
1080 break;
1081 case 'O':
1082 name = "'Output";
1083 break;
1084 default:
1085 goto unknown;
1086 }
1087 p += 2;
1088 strcpy (d, name);
1089 d += strlen (name);
1090 }
1091 else if (p[0] == 'D')
1092 {
1093 /* Controlled type operation. */
1094 const char *name;
1095 switch (p[1])
1096 {
1097 case 'F':
1098 name = ".Finalize";
1099 break;
1100 case 'A':
1101 name = ".Adjust";
1102 break;
1103 default:
1104 goto unknown;
1105 }
1106 strcpy (d, name);
1107 d += strlen (name);
1108 break;
1109 }
1110
1111 if (p[0] == '_')
1112 {
1113 /* Separator. */
1114 if (p[1] == '_')
1115 {
1116 /* Standard separator. Handled first. */
1117 p += 2;
1118
1119 if (ISDIGIT (*p))
1120 {
1121 /* Overloading number. */
1122 do
1123 p++;
1124 while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
1125 if (*p == 'X')
1126 {
1127 p++;
1128 while (p[0] == 'n' || p[0] == 'b')
1129 p++;
1130 }
1131 }
1132 else if (p[0] == '_' && p[1] != '_')
1133 {
1134 /* Special names. */
1135 static const char * const special[][2] = {
1136 { "_elabb", "'Elab_Body" },
1137 { "_elabs", "'Elab_Spec" },
1138 { "_size", "'Size" },
1139 { "_alignment", "'Alignment" },
1140 { "_assign", ".\":=\"" },
1141 { NULL, NULL }
1142 };
1143 int k;
1144
1145 for (k = 0; special[k][0] != NULL; k++)
1146 {
1147 size_t slen = strlen (special[k][0]);
1148 if (strncmp (p, special[k][0], slen) == 0)
1149 {
1150 p += slen;
1151 slen = strlen (special[k][1]);
1152 memcpy (d, special[k][1], slen);
1153 d += slen;
1154 break;
1155 }
1156 }
1157 if (special[k][0] != NULL)
1158 break;
1159 else
1160 goto unknown;
1161 }
1162 else
1163 {
1164 *d++ = '.';
1165 continue;
1166 }
1167 }
1168 else if (p[1] == 'B' || p[1] == 'E')
1169 {
1170 /* Entry Body or barrier Evaluation. */
1171 p += 2;
1172 while (ISDIGIT (*p))
1173 p++;
1174 if (p[0] == 's' && p[1] == 0)
1175 break;
1176 else
1177 goto unknown;
1178 }
1179 else
1180 goto unknown;
1181 }
1182
1183 if (p[0] == '.' && ISDIGIT (p[1]))
1184 {
1185 /* Nested subprogram. */
1186 p += 2;
1187 while (ISDIGIT (*p))
1188 p++;
1189 }
1190 if (*p == 0)
1191 {
1192 /* End of mangled name. */
1193 break;
1194 }
1195 else
1196 goto unknown;
1197 }
1198 *d = 0;
1199 return demangled;
1200
1201 unknown:
1202 XDELETEVEC (demangled);
1203 len0 = strlen (mangled);
1204 demangled = XNEWVEC (char, len0 + 3);
1205
1206 if (mangled[0] == '<')
1207 strcpy (demangled, mangled);
1208 else
1209 sprintf (demangled, "<%s>", mangled);
1210
1211 return demangled;
1212 }
1213
1214 /* This function performs most of what cplus_demangle use to do, but
1215 to be able to demangle a name with a B, K or n code, we need to
1216 have a longer term memory of what types have been seen. The original
1217 now initializes and cleans up the squangle code info, while internal
1218 calls go directly to this routine to avoid resetting that info. */
1219
1220 static char *
1221 internal_cplus_demangle (struct work_stuff *work, const char *mangled)
1222 {
1223
1224 string decl;
1225 int success = 0;
1226 char *demangled = NULL;
1227 int s1, s2, s3, s4;
1228 s1 = work->constructor;
1229 s2 = work->destructor;
1230 s3 = work->static_type;
1231 s4 = work->type_quals;
1232 work->constructor = work->destructor = 0;
1233 work->type_quals = TYPE_UNQUALIFIED;
1234 work->dllimported = 0;
1235
1236 if ((mangled != NULL) && (*mangled != '\0'))
1237 {
1238 string_init (&decl);
1239
1240 /* First check to see if gnu style demangling is active and if the
1241 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1242 recognize one of the gnu special forms rather than looking for a
1243 standard prefix. In particular, don't worry about whether there
1244 is a "__" string in the mangled string. Consider "_$_5__foo" for
1245 example. */
1246
1247 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
1248 {
1249 success = gnu_special (work, &mangled, &decl);
1250 if (!success)
1251 {
1252 delete_work_stuff (work);
1253 string_delete (&decl);
1254 }
1255 }
1256 if (!success)
1257 {
1258 success = demangle_prefix (work, &mangled, &decl);
1259 }
1260 if (success && (*mangled != '\0'))
1261 {
1262 success = demangle_signature (work, &mangled, &decl);
1263 }
1264 if (work->constructor == 2)
1265 {
1266 string_prepend (&decl, "global constructors keyed to ");
1267 work->constructor = 0;
1268 }
1269 else if (work->destructor == 2)
1270 {
1271 string_prepend (&decl, "global destructors keyed to ");
1272 work->destructor = 0;
1273 }
1274 else if (work->dllimported == 1)
1275 {
1276 string_prepend (&decl, "import stub for ");
1277 work->dllimported = 0;
1278 }
1279 demangled = mop_up (work, &decl, success);
1280 }
1281 work->constructor = s1;
1282 work->destructor = s2;
1283 work->static_type = s3;
1284 work->type_quals = s4;
1285 return demangled;
1286 }
1287
1288
1289 /* Clear out and squangling related storage */
1290 static void
1291 squangle_mop_up (struct work_stuff *work)
1292 {
1293 /* clean up the B and K type mangling types. */
1294 forget_B_and_K_types (work);
1295 if (work -> btypevec != NULL)
1296 {
1297 free ((char *) work -> btypevec);
1298 work->btypevec = NULL;
1299 work->bsize = 0;
1300 }
1301 if (work -> ktypevec != NULL)
1302 {
1303 free ((char *) work -> ktypevec);
1304 work->ktypevec = NULL;
1305 work->ksize = 0;
1306 }
1307 }
1308
1309
1310 /* Copy the work state and storage. */
1311
1312 static void
1313 work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
1314 {
1315 int i;
1316
1317 delete_work_stuff (to);
1318
1319 /* Shallow-copy scalars. */
1320 memcpy (to, from, sizeof (*to));
1321
1322 /* Deep-copy dynamic storage. */
1323 if (from->typevec_size)
1324 to->typevec = XNEWVEC (char *, from->typevec_size);
1325
1326 for (i = 0; i < from->ntypes; i++)
1327 {
1328 int len = strlen (from->typevec[i]) + 1;
1329
1330 to->typevec[i] = XNEWVEC (char, len);
1331 memcpy (to->typevec[i], from->typevec[i], len);
1332 }
1333
1334 if (from->ksize)
1335 to->ktypevec = XNEWVEC (char *, from->ksize);
1336
1337 for (i = 0; i < from->numk; i++)
1338 {
1339 int len = strlen (from->ktypevec[i]) + 1;
1340
1341 to->ktypevec[i] = XNEWVEC (char, len);
1342 memcpy (to->ktypevec[i], from->ktypevec[i], len);
1343 }
1344
1345 if (from->bsize)
1346 to->btypevec = XNEWVEC (char *, from->bsize);
1347
1348 for (i = 0; i < from->numb; i++)
1349 {
1350 int len = strlen (from->btypevec[i]) + 1;
1351
1352 to->btypevec[i] = XNEWVEC (char , len);
1353 memcpy (to->btypevec[i], from->btypevec[i], len);
1354 }
1355
1356 if (from->proctypevec)
1357 to->proctypevec =
1358 XDUPVEC (int, from->proctypevec, from->proctypevec_size);
1359
1360 if (from->ntmpl_args)
1361 to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args);
1362
1363 for (i = 0; i < from->ntmpl_args; i++)
1364 {
1365 int len = strlen (from->tmpl_argvec[i]) + 1;
1366
1367 to->tmpl_argvec[i] = XNEWVEC (char, len);
1368 memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
1369 }
1370
1371 if (from->previous_argument)
1372 {
1373 to->previous_argument = XNEW (string);
1374 string_init (to->previous_argument);
1375 string_appends (to->previous_argument, from->previous_argument);
1376 }
1377 }
1378
1379
1380 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1381
1382 static void
1383 delete_non_B_K_work_stuff (struct work_stuff *work)
1384 {
1385 /* Discard the remembered types, if any. */
1386
1387 forget_types (work);
1388 if (work->typevec != NULL)
1389 {
1390 free ((char *) work->typevec);
1391 work->typevec = NULL;
1392 work->typevec_size = 0;
1393 }
1394 if (work->proctypevec != NULL)
1395 {
1396 free (work->proctypevec);
1397 work->proctypevec = NULL;
1398 work->proctypevec_size = 0;
1399 }
1400 if (work->tmpl_argvec)
1401 {
1402 int i;
1403
1404 for (i = 0; i < work->ntmpl_args; i++)
1405 free ((char*) work->tmpl_argvec[i]);
1406
1407 free ((char*) work->tmpl_argvec);
1408 work->tmpl_argvec = NULL;
1409 }
1410 if (work->previous_argument)
1411 {
1412 string_delete (work->previous_argument);
1413 free ((char*) work->previous_argument);
1414 work->previous_argument = NULL;
1415 }
1416 }
1417
1418
1419 /* Delete all dynamic storage in work_stuff. */
1420 static void
1421 delete_work_stuff (struct work_stuff *work)
1422 {
1423 delete_non_B_K_work_stuff (work);
1424 squangle_mop_up (work);
1425 }
1426
1427
1428 /* Clear out any mangled storage */
1429
1430 static char *
1431 mop_up (struct work_stuff *work, string *declp, int success)
1432 {
1433 char *demangled = NULL;
1434
1435 delete_non_B_K_work_stuff (work);
1436
1437 /* If demangling was successful, ensure that the demangled string is null
1438 terminated and return it. Otherwise, free the demangling decl. */
1439
1440 if (!success)
1441 {
1442 string_delete (declp);
1443 }
1444 else
1445 {
1446 string_appendn (declp, "", 1);
1447 demangled = declp->b;
1448 }
1449 return (demangled);
1450 }
1451
1452 /*
1453
1454 LOCAL FUNCTION
1455
1456 demangle_signature -- demangle the signature part of a mangled name
1457
1458 SYNOPSIS
1459
1460 static int
1461 demangle_signature (struct work_stuff *work, const char **mangled,
1462 string *declp);
1463
1464 DESCRIPTION
1465
1466 Consume and demangle the signature portion of the mangled name.
1467
1468 DECLP is the string where demangled output is being built. At
1469 entry it contains the demangled root name from the mangled name
1470 prefix. I.E. either a demangled operator name or the root function
1471 name. In some special cases, it may contain nothing.
1472
1473 *MANGLED points to the current unconsumed location in the mangled
1474 name. As tokens are consumed and demangling is performed, the
1475 pointer is updated to continuously point at the next token to
1476 be consumed.
1477
1478 Demangling GNU style mangled names is nasty because there is no
1479 explicit token that marks the start of the outermost function
1480 argument list. */
1481
1482 static int
1483 demangle_signature (struct work_stuff *work,
1484 const char **mangled, string *declp)
1485 {
1486 int success = 1;
1487 int func_done = 0;
1488 int expect_func = 0;
1489 int expect_return_type = 0;
1490 const char *oldmangled = NULL;
1491 string trawname;
1492 string tname;
1493
1494 while (success && (**mangled != '\0'))
1495 {
1496 switch (**mangled)
1497 {
1498 case 'Q':
1499 oldmangled = *mangled;
1500 success = demangle_qualified (work, mangled, declp, 1, 0);
1501 if (success)
1502 remember_type (work, oldmangled, *mangled - oldmangled);
1503 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1504 expect_func = 1;
1505 oldmangled = NULL;
1506 break;
1507
1508 case 'K':
1509 oldmangled = *mangled;
1510 success = demangle_qualified (work, mangled, declp, 1, 0);
1511 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1512 {
1513 expect_func = 1;
1514 }
1515 oldmangled = NULL;
1516 break;
1517
1518 case 'S':
1519 /* Static member function */
1520 if (oldmangled == NULL)
1521 {
1522 oldmangled = *mangled;
1523 }
1524 (*mangled)++;
1525 work -> static_type = 1;
1526 break;
1527
1528 case 'C':
1529 case 'V':
1530 case 'u':
1531 work->type_quals |= code_for_qualifier (**mangled);
1532
1533 /* a qualified member function */
1534 if (oldmangled == NULL)
1535 oldmangled = *mangled;
1536 (*mangled)++;
1537 break;
1538
1539 case 'L':
1540 /* Local class name follows after "Lnnn_" */
1541 if (HP_DEMANGLING)
1542 {
1543 while (**mangled && (**mangled != '_'))
1544 (*mangled)++;
1545 if (!**mangled)
1546 success = 0;
1547 else
1548 (*mangled)++;
1549 }
1550 else
1551 success = 0;
1552 break;
1553
1554 case '0': case '1': case '2': case '3': case '4':
1555 case '5': case '6': case '7': case '8': case '9':
1556 if (oldmangled == NULL)
1557 {
1558 oldmangled = *mangled;
1559 }
1560 work->temp_start = -1; /* uppermost call to demangle_class */
1561 success = demangle_class (work, mangled, declp);
1562 if (success)
1563 {
1564 remember_type (work, oldmangled, *mangled - oldmangled);
1565 }
1566 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1567 {
1568 /* EDG and others will have the "F", so we let the loop cycle
1569 if we are looking at one. */
1570 if (**mangled != 'F')
1571 expect_func = 1;
1572 }
1573 oldmangled = NULL;
1574 break;
1575
1576 case 'B':
1577 {
1578 string s;
1579 success = do_type (work, mangled, &s);
1580 if (success)
1581 {
1582 string_append (&s, SCOPE_STRING (work));
1583 string_prepends (declp, &s);
1584 string_delete (&s);
1585 }
1586 oldmangled = NULL;
1587 expect_func = 1;
1588 }
1589 break;
1590
1591 case 'F':
1592 /* Function */
1593 /* ARM/HP style demangling includes a specific 'F' character after
1594 the class name. For GNU style, it is just implied. So we can
1595 safely just consume any 'F' at this point and be compatible
1596 with either style. */
1597
1598 oldmangled = NULL;
1599 func_done = 1;
1600 (*mangled)++;
1601
1602 /* For lucid/ARM/HP style we have to forget any types we might
1603 have remembered up to this point, since they were not argument
1604 types. GNU style considers all types seen as available for
1605 back references. See comment in demangle_args() */
1606
1607 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1608 {
1609 forget_types (work);
1610 }
1611 success = demangle_args (work, mangled, declp);
1612 /* After picking off the function args, we expect to either
1613 find the function return type (preceded by an '_') or the
1614 end of the string. */
1615 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1616 {
1617 ++(*mangled);
1618 /* At this level, we do not care about the return type. */
1619 success = do_type (work, mangled, &tname);
1620 string_delete (&tname);
1621 }
1622
1623 break;
1624
1625 case 't':
1626 /* G++ Template */
1627 string_init(&trawname);
1628 string_init(&tname);
1629 if (oldmangled == NULL)
1630 {
1631 oldmangled = *mangled;
1632 }
1633 success = demangle_template (work, mangled, &tname,
1634 &trawname, 1, 1);
1635 if (success)
1636 {
1637 remember_type (work, oldmangled, *mangled - oldmangled);
1638 }
1639 string_append (&tname, SCOPE_STRING (work));
1640
1641 string_prepends(declp, &tname);
1642 if (work -> destructor & 1)
1643 {
1644 string_prepend (&trawname, "~");
1645 string_appends (declp, &trawname);
1646 work->destructor -= 1;
1647 }
1648 if ((work->constructor & 1) || (work->destructor & 1))
1649 {
1650 string_appends (declp, &trawname);
1651 work->constructor -= 1;
1652 }
1653 string_delete(&trawname);
1654 string_delete(&tname);
1655 oldmangled = NULL;
1656 expect_func = 1;
1657 break;
1658
1659 case '_':
1660 if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1661 {
1662 /* Read the return type. */
1663 string return_type;
1664
1665 (*mangled)++;
1666 success = do_type (work, mangled, &return_type);
1667 APPEND_BLANK (&return_type);
1668
1669 string_prepends (declp, &return_type);
1670 string_delete (&return_type);
1671 break;
1672 }
1673 else
1674 /* At the outermost level, we cannot have a return type specified,
1675 so if we run into another '_' at this point we are dealing with
1676 a mangled name that is either bogus, or has been mangled by
1677 some algorithm we don't know how to deal with. So just
1678 reject the entire demangling. */
1679 /* However, "_nnn" is an expected suffix for alternate entry point
1680 numbered nnn for a function, with HP aCC, so skip over that
1681 without reporting failure. pai/1997-09-04 */
1682 if (HP_DEMANGLING)
1683 {
1684 (*mangled)++;
1685 while (**mangled && ISDIGIT ((unsigned char)**mangled))
1686 (*mangled)++;
1687 }
1688 else
1689 success = 0;
1690 break;
1691
1692 case 'H':
1693 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1694 {
1695 /* A G++ template function. Read the template arguments. */
1696 success = demangle_template (work, mangled, declp, 0, 0,
1697 0);
1698 if (!(work->constructor & 1))
1699 expect_return_type = 1;
1700 if (!**mangled)
1701 success = 0;
1702 else
1703 (*mangled)++;
1704 break;
1705 }
1706 /* fall through */
1707
1708 default:
1709 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1710 {
1711 /* Assume we have stumbled onto the first outermost function
1712 argument token, and start processing args. */
1713 func_done = 1;
1714 success = demangle_args (work, mangled, declp);
1715 }
1716 else
1717 {
1718 /* Non-GNU demanglers use a specific token to mark the start
1719 of the outermost function argument tokens. Typically 'F',
1720 for ARM/HP-demangling, for example. So if we find something
1721 we are not prepared for, it must be an error. */
1722 success = 0;
1723 }
1724 break;
1725 }
1726 /*
1727 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1728 */
1729 {
1730 if (success && expect_func)
1731 {
1732 func_done = 1;
1733 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1734 {
1735 forget_types (work);
1736 }
1737 success = demangle_args (work, mangled, declp);
1738 /* Since template include the mangling of their return types,
1739 we must set expect_func to 0 so that we don't try do
1740 demangle more arguments the next time we get here. */
1741 expect_func = 0;
1742 }
1743 }
1744 }
1745 if (success && !func_done)
1746 {
1747 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1748 {
1749 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1750 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1751 first case, and need to ensure that the '(void)' gets added to
1752 the current declp. Note that with ARM/HP, the first case
1753 represents the name of a static data member 'foo::bar',
1754 which is in the current declp, so we leave it alone. */
1755 success = demangle_args (work, mangled, declp);
1756 }
1757 }
1758 if (success && PRINT_ARG_TYPES)
1759 {
1760 if (work->static_type)
1761 string_append (declp, " static");
1762 if (work->type_quals != TYPE_UNQUALIFIED)
1763 {
1764 APPEND_BLANK (declp);
1765 string_append (declp, qualifier_string (work->type_quals));
1766 }
1767 }
1768
1769 return (success);
1770 }
1771
1772 #if 0
1773
1774 static int
1775 demangle_method_args (struct work_stuff *work, const char **mangled,
1776 string *declp)
1777 {
1778 int success = 0;
1779
1780 if (work -> static_type)
1781 {
1782 string_append (declp, *mangled + 1);
1783 *mangled += strlen (*mangled);
1784 success = 1;
1785 }
1786 else
1787 {
1788 success = demangle_args (work, mangled, declp);
1789 }
1790 return (success);
1791 }
1792
1793 #endif
1794
1795 static int
1796 demangle_template_template_parm (struct work_stuff *work,
1797 const char **mangled, string *tname)
1798 {
1799 int i;
1800 int r;
1801 int need_comma = 0;
1802 int success = 1;
1803 string temp;
1804
1805 string_append (tname, "template <");
1806 /* get size of template parameter list */
1807 if (get_count (mangled, &r))
1808 {
1809 for (i = 0; i < r; i++)
1810 {
1811 if (need_comma)
1812 {
1813 string_append (tname, ", ");
1814 }
1815
1816 /* Z for type parameters */
1817 if (**mangled == 'Z')
1818 {
1819 (*mangled)++;
1820 string_append (tname, "class");
1821 }
1822 /* z for template parameters */
1823 else if (**mangled == 'z')
1824 {
1825 (*mangled)++;
1826 success =
1827 demangle_template_template_parm (work, mangled, tname);
1828 if (!success)
1829 {
1830 break;
1831 }
1832 }
1833 else
1834 {
1835 /* temp is initialized in do_type */
1836 success = do_type (work, mangled, &temp);
1837 if (success)
1838 {
1839 string_appends (tname, &temp);
1840 }
1841 string_delete(&temp);
1842 if (!success)
1843 {
1844 break;
1845 }
1846 }
1847 need_comma = 1;
1848 }
1849
1850 }
1851 if (tname->p[-1] == '>')
1852 string_append (tname, " ");
1853 string_append (tname, "> class");
1854 return (success);
1855 }
1856
1857 static int
1858 demangle_expression (struct work_stuff *work, const char **mangled,
1859 string *s, type_kind_t tk)
1860 {
1861 int need_operator = 0;
1862 int success;
1863
1864 success = 1;
1865 string_appendn (s, "(", 1);
1866 (*mangled)++;
1867 while (success && **mangled != 'W' && **mangled != '\0')
1868 {
1869 if (need_operator)
1870 {
1871 size_t i;
1872 size_t len;
1873
1874 success = 0;
1875
1876 len = strlen (*mangled);
1877
1878 for (i = 0; i < ARRAY_SIZE (optable); ++i)
1879 {
1880 size_t l = strlen (optable[i].in);
1881
1882 if (l <= len
1883 && memcmp (optable[i].in, *mangled, l) == 0)
1884 {
1885 string_appendn (s, " ", 1);
1886 string_append (s, optable[i].out);
1887 string_appendn (s, " ", 1);
1888 success = 1;
1889 (*mangled) += l;
1890 break;
1891 }
1892 }
1893
1894 if (!success)
1895 break;
1896 }
1897 else
1898 need_operator = 1;
1899
1900 success = demangle_template_value_parm (work, mangled, s, tk);
1901 }
1902
1903 if (**mangled != 'W')
1904 success = 0;
1905 else
1906 {
1907 string_appendn (s, ")", 1);
1908 (*mangled)++;
1909 }
1910
1911 return success;
1912 }
1913
1914 static int
1915 demangle_integral_value (struct work_stuff *work,
1916 const char **mangled, string *s)
1917 {
1918 int success;
1919
1920 if (**mangled == 'E')
1921 success = demangle_expression (work, mangled, s, tk_integral);
1922 else if (**mangled == 'Q' || **mangled == 'K')
1923 success = demangle_qualified (work, mangled, s, 0, 1);
1924 else
1925 {
1926 int value;
1927
1928 /* By default, we let the number decide whether we shall consume an
1929 underscore. */
1930 int multidigit_without_leading_underscore = 0;
1931 int leave_following_underscore = 0;
1932
1933 success = 0;
1934
1935 if (**mangled == '_')
1936 {
1937 if (mangled[0][1] == 'm')
1938 {
1939 /* Since consume_count_with_underscores does not handle the
1940 `m'-prefix we must do it here, using consume_count and
1941 adjusting underscores: we have to consume the underscore
1942 matching the prepended one. */
1943 multidigit_without_leading_underscore = 1;
1944 string_appendn (s, "-", 1);
1945 (*mangled) += 2;
1946 }
1947 else
1948 {
1949 /* Do not consume a following underscore;
1950 consume_count_with_underscores will consume what
1951 should be consumed. */
1952 leave_following_underscore = 1;
1953 }
1954 }
1955 else
1956 {
1957 /* Negative numbers are indicated with a leading `m'. */
1958 if (**mangled == 'm')
1959 {
1960 string_appendn (s, "-", 1);
1961 (*mangled)++;
1962 }
1963 /* Since consume_count_with_underscores does not handle
1964 multi-digit numbers that do not start with an underscore,
1965 and this number can be an integer template parameter,
1966 we have to call consume_count. */
1967 multidigit_without_leading_underscore = 1;
1968 /* These multi-digit numbers never end on an underscore,
1969 so if there is one then don't eat it. */
1970 leave_following_underscore = 1;
1971 }
1972
1973 /* We must call consume_count if we expect to remove a trailing
1974 underscore, since consume_count_with_underscores expects
1975 the leading underscore (that we consumed) if it is to handle
1976 multi-digit numbers. */
1977 if (multidigit_without_leading_underscore)
1978 value = consume_count (mangled);
1979 else
1980 value = consume_count_with_underscores (mangled);
1981
1982 if (value != -1)
1983 {
1984 char buf[INTBUF_SIZE];
1985 sprintf (buf, "%d", value);
1986 string_append (s, buf);
1987
1988 /* Numbers not otherwise delimited, might have an underscore
1989 appended as a delimeter, which we should skip.
1990
1991 ??? This used to always remove a following underscore, which
1992 is wrong. If other (arbitrary) cases are followed by an
1993 underscore, we need to do something more radical. */
1994
1995 if ((value > 9 || multidigit_without_leading_underscore)
1996 && ! leave_following_underscore
1997 && **mangled == '_')
1998 (*mangled)++;
1999
2000 /* All is well. */
2001 success = 1;
2002 }
2003 }
2004
2005 return success;
2006 }
2007
2008 /* Demangle the real value in MANGLED. */
2009
2010 static int
2011 demangle_real_value (struct work_stuff *work,
2012 const char **mangled, string *s)
2013 {
2014 if (**mangled == 'E')
2015 return demangle_expression (work, mangled, s, tk_real);
2016
2017 if (**mangled == 'm')
2018 {
2019 string_appendn (s, "-", 1);
2020 (*mangled)++;
2021 }
2022 while (ISDIGIT ((unsigned char)**mangled))
2023 {
2024 string_appendn (s, *mangled, 1);
2025 (*mangled)++;
2026 }
2027 if (**mangled == '.') /* fraction */
2028 {
2029 string_appendn (s, ".", 1);
2030 (*mangled)++;
2031 while (ISDIGIT ((unsigned char)**mangled))
2032 {
2033 string_appendn (s, *mangled, 1);
2034 (*mangled)++;
2035 }
2036 }
2037 if (**mangled == 'e') /* exponent */
2038 {
2039 string_appendn (s, "e", 1);
2040 (*mangled)++;
2041 while (ISDIGIT ((unsigned char)**mangled))
2042 {
2043 string_appendn (s, *mangled, 1);
2044 (*mangled)++;
2045 }
2046 }
2047
2048 return 1;
2049 }
2050
2051 static int
2052 demangle_template_value_parm (struct work_stuff *work, const char **mangled,
2053 string *s, type_kind_t tk)
2054 {
2055 int success = 1;
2056
2057 if (**mangled == 'Y')
2058 {
2059 /* The next argument is a template parameter. */
2060 int idx;
2061
2062 (*mangled)++;
2063 idx = consume_count_with_underscores (mangled);
2064 if (idx == -1
2065 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2066 || consume_count_with_underscores (mangled) == -1)
2067 return -1;
2068 if (work->tmpl_argvec)
2069 string_append (s, work->tmpl_argvec[idx]);
2070 else
2071 string_append_template_idx (s, idx);
2072 }
2073 else if (tk == tk_integral)
2074 success = demangle_integral_value (work, mangled, s);
2075 else if (tk == tk_char)
2076 {
2077 char tmp[2];
2078 int val;
2079 if (**mangled == 'm')
2080 {
2081 string_appendn (s, "-", 1);
2082 (*mangled)++;
2083 }
2084 string_appendn (s, "'", 1);
2085 val = consume_count(mangled);
2086 if (val <= 0)
2087 success = 0;
2088 else
2089 {
2090 tmp[0] = (char)val;
2091 tmp[1] = '\0';
2092 string_appendn (s, &tmp[0], 1);
2093 string_appendn (s, "'", 1);
2094 }
2095 }
2096 else if (tk == tk_bool)
2097 {
2098 int val = consume_count (mangled);
2099 if (val == 0)
2100 string_appendn (s, "false", 5);
2101 else if (val == 1)
2102 string_appendn (s, "true", 4);
2103 else
2104 success = 0;
2105 }
2106 else if (tk == tk_real)
2107 success = demangle_real_value (work, mangled, s);
2108 else if (tk == tk_pointer || tk == tk_reference
2109 || tk == tk_rvalue_reference)
2110 {
2111 if (**mangled == 'Q')
2112 success = demangle_qualified (work, mangled, s,
2113 /*isfuncname=*/0,
2114 /*append=*/1);
2115 else
2116 {
2117 int symbol_len = consume_count (mangled);
2118 if (symbol_len == -1
2119 || symbol_len > (long) strlen (*mangled))
2120 return -1;
2121 if (symbol_len == 0)
2122 string_appendn (s, "0", 1);
2123 else
2124 {
2125 char *p = XNEWVEC (char, symbol_len + 1), *q;
2126 strncpy (p, *mangled, symbol_len);
2127 p [symbol_len] = '\0';
2128 /* We use cplus_demangle here, rather than
2129 internal_cplus_demangle, because the name of the entity
2130 mangled here does not make use of any of the squangling
2131 or type-code information we have built up thus far; it is
2132 mangled independently. */
2133 q = cplus_demangle (p, work->options);
2134 if (tk == tk_pointer)
2135 string_appendn (s, "&", 1);
2136 /* FIXME: Pointer-to-member constants should get a
2137 qualifying class name here. */
2138 if (q)
2139 {
2140 string_append (s, q);
2141 free (q);
2142 }
2143 else
2144 string_append (s, p);
2145 free (p);
2146 }
2147 *mangled += symbol_len;
2148 }
2149 }
2150
2151 return success;
2152 }
2153
2154 /* Demangle the template name in MANGLED. The full name of the
2155 template (e.g., S<int>) is placed in TNAME. The name without the
2156 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2157 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2158 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2159 the template is remembered in the list of back-referenceable
2160 types. */
2161
2162 static int
2163 demangle_template (struct work_stuff *work, const char **mangled,
2164 string *tname, string *trawname,
2165 int is_type, int remember)
2166 {
2167 int i;
2168 int r;
2169 int need_comma = 0;
2170 int success = 0;
2171 int is_java_array = 0;
2172 string temp;
2173
2174 (*mangled)++;
2175 if (is_type)
2176 {
2177 /* get template name */
2178 if (**mangled == 'z')
2179 {
2180 int idx;
2181 (*mangled)++;
2182 if (**mangled == '\0')
2183 return (0);
2184 (*mangled)++;
2185
2186 idx = consume_count_with_underscores (mangled);
2187 if (idx == -1
2188 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2189 || consume_count_with_underscores (mangled) == -1)
2190 return (0);
2191
2192 if (work->tmpl_argvec)
2193 {
2194 string_append (tname, work->tmpl_argvec[idx]);
2195 if (trawname)
2196 string_append (trawname, work->tmpl_argvec[idx]);
2197 }
2198 else
2199 {
2200 string_append_template_idx (tname, idx);
2201 if (trawname)
2202 string_append_template_idx (trawname, idx);
2203 }
2204 }
2205 else
2206 {
2207 if ((r = consume_count (mangled)) <= 0
2208 || (int) strlen (*mangled) < r)
2209 {
2210 return (0);
2211 }
2212 is_java_array = (work -> options & DMGL_JAVA)
2213 && strncmp (*mangled, "JArray1Z", 8) == 0;
2214 if (! is_java_array)
2215 {
2216 string_appendn (tname, *mangled, r);
2217 }
2218 if (trawname)
2219 string_appendn (trawname, *mangled, r);
2220 *mangled += r;
2221 }
2222 }
2223 if (!is_java_array)
2224 string_append (tname, "<");
2225 /* get size of template parameter list */
2226 if (!get_count (mangled, &r))
2227 {
2228 return (0);
2229 }
2230 if (!is_type)
2231 {
2232 /* Create an array for saving the template argument values. */
2233 work->tmpl_argvec = XNEWVEC (char *, r);
2234 work->ntmpl_args = r;
2235 for (i = 0; i < r; i++)
2236 work->tmpl_argvec[i] = 0;
2237 }
2238 for (i = 0; i < r; i++)
2239 {
2240 if (need_comma)
2241 {
2242 string_append (tname, ", ");
2243 }
2244 /* Z for type parameters */
2245 if (**mangled == 'Z')
2246 {
2247 (*mangled)++;
2248 /* temp is initialized in do_type */
2249 success = do_type (work, mangled, &temp);
2250 if (success)
2251 {
2252 string_appends (tname, &temp);
2253
2254 if (!is_type)
2255 {
2256 /* Save the template argument. */
2257 int len = temp.p - temp.b;
2258 work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2259 memcpy (work->tmpl_argvec[i], temp.b, len);
2260 work->tmpl_argvec[i][len] = '\0';
2261 }
2262 }
2263 string_delete(&temp);
2264 if (!success)
2265 {
2266 break;
2267 }
2268 }
2269 /* z for template parameters */
2270 else if (**mangled == 'z')
2271 {
2272 int r2;
2273 (*mangled)++;
2274 success = demangle_template_template_parm (work, mangled, tname);
2275
2276 if (success
2277 && (r2 = consume_count (mangled)) > 0
2278 && (int) strlen (*mangled) >= r2)
2279 {
2280 string_append (tname, " ");
2281 string_appendn (tname, *mangled, r2);
2282 if (!is_type)
2283 {
2284 /* Save the template argument. */
2285 int len = r2;
2286 work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2287 memcpy (work->tmpl_argvec[i], *mangled, len);
2288 work->tmpl_argvec[i][len] = '\0';
2289 }
2290 *mangled += r2;
2291 }
2292 if (!success)
2293 {
2294 break;
2295 }
2296 }
2297 else
2298 {
2299 string param;
2300 string* s;
2301
2302 /* otherwise, value parameter */
2303
2304 /* temp is initialized in do_type */
2305 success = do_type (work, mangled, &temp);
2306 string_delete(&temp);
2307 if (!success)
2308 break;
2309
2310 if (!is_type)
2311 {
2312 s = &param;
2313 string_init (s);
2314 }
2315 else
2316 s = tname;
2317
2318 success = demangle_template_value_parm (work, mangled, s,
2319 (type_kind_t) success);
2320
2321 if (!success)
2322 {
2323 if (!is_type)
2324 string_delete (s);
2325 success = 0;
2326 break;
2327 }
2328
2329 if (!is_type)
2330 {
2331 int len = s->p - s->b;
2332 work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2333 memcpy (work->tmpl_argvec[i], s->b, len);
2334 work->tmpl_argvec[i][len] = '\0';
2335
2336 string_appends (tname, s);
2337 string_delete (s);
2338 }
2339 }
2340 need_comma = 1;
2341 }
2342 if (is_java_array)
2343 {
2344 string_append (tname, "[]");
2345 }
2346 else
2347 {
2348 if (tname->p[-1] == '>')
2349 string_append (tname, " ");
2350 string_append (tname, ">");
2351 }
2352
2353 if (is_type && remember)
2354 {
2355 const int bindex = register_Btype (work);
2356 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
2357 }
2358
2359 /*
2360 if (work -> static_type)
2361 {
2362 string_append (declp, *mangled + 1);
2363 *mangled += strlen (*mangled);
2364 success = 1;
2365 }
2366 else
2367 {
2368 success = demangle_args (work, mangled, declp);
2369 }
2370 }
2371 */
2372 return (success);
2373 }
2374
2375 static int
2376 arm_pt (struct work_stuff *work, const char *mangled,
2377 int n, const char **anchor, const char **args)
2378 {
2379 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2380 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2381 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
2382 {
2383 int len;
2384 *args = *anchor + 6;
2385 len = consume_count (args);
2386 if (len == -1)
2387 return 0;
2388 if (*args + len == mangled + n && **args == '_')
2389 {
2390 ++*args;
2391 return 1;
2392 }
2393 }
2394 if (AUTO_DEMANGLING || EDG_DEMANGLING)
2395 {
2396 if ((*anchor = strstr (mangled, "__tm__"))
2397 || (*anchor = strstr (mangled, "__ps__"))
2398 || (*anchor = strstr (mangled, "__pt__")))
2399 {
2400 int len;
2401 *args = *anchor + 6;
2402 len = consume_count (args);
2403 if (len == -1)
2404 return 0;
2405 if (*args + len == mangled + n && **args == '_')
2406 {
2407 ++*args;
2408 return 1;
2409 }
2410 }
2411 else if ((*anchor = strstr (mangled, "__S")))
2412 {
2413 int len;
2414 *args = *anchor + 3;
2415 len = consume_count (args);
2416 if (len == -1)
2417 return 0;
2418 if (*args + len == mangled + n && **args == '_')
2419 {
2420 ++*args;
2421 return 1;
2422 }
2423 }
2424 }
2425
2426 return 0;
2427 }
2428
2429 static void
2430 demangle_arm_hp_template (struct work_stuff *work, const char **mangled,
2431 int n, string *declp)
2432 {
2433 const char *p;
2434 const char *args;
2435 const char *e = *mangled + n;
2436 string arg;
2437
2438 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2439 template args */
2440 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
2441 {
2442 char *start_spec_args = NULL;
2443 int hold_options;
2444
2445 /* First check for and omit template specialization pseudo-arguments,
2446 such as in "Spec<#1,#1.*>" */
2447 start_spec_args = strchr (*mangled, '<');
2448 if (start_spec_args && (start_spec_args - *mangled < n))
2449 string_appendn (declp, *mangled, start_spec_args - *mangled);
2450 else
2451 string_appendn (declp, *mangled, n);
2452 (*mangled) += n + 1;
2453 string_init (&arg);
2454 if (work->temp_start == -1) /* non-recursive call */
2455 work->temp_start = declp->p - declp->b;
2456
2457 /* We want to unconditionally demangle parameter types in
2458 template parameters. */
2459 hold_options = work->options;
2460 work->options |= DMGL_PARAMS;
2461
2462 string_append (declp, "<");
2463 while (1)
2464 {
2465 string_delete (&arg);
2466 switch (**mangled)
2467 {
2468 case 'T':
2469 /* 'T' signals a type parameter */
2470 (*mangled)++;
2471 if (!do_type (work, mangled, &arg))
2472 goto hpacc_template_args_done;
2473 break;
2474
2475 case 'U':
2476 case 'S':
2477 /* 'U' or 'S' signals an integral value */
2478 if (!do_hpacc_template_const_value (work, mangled, &arg))
2479 goto hpacc_template_args_done;
2480 break;
2481
2482 case 'A':
2483 /* 'A' signals a named constant expression (literal) */
2484 if (!do_hpacc_template_literal (work, mangled, &arg))
2485 goto hpacc_template_args_done;
2486 break;
2487
2488 default:
2489 /* Today, 1997-09-03, we have only the above types
2490 of template parameters */
2491 /* FIXME: maybe this should fail and return null */
2492 goto hpacc_template_args_done;
2493 }
2494 string_appends (declp, &arg);
2495 /* Check if we're at the end of template args.
2496 0 if at end of static member of template class,
2497 _ if done with template args for a function */
2498 if ((**mangled == '\000') || (**mangled == '_'))
2499 break;
2500 else
2501 string_append (declp, ",");
2502 }
2503 hpacc_template_args_done:
2504 string_append (declp, ">");
2505 string_delete (&arg);
2506 if (**mangled == '_')
2507 (*mangled)++;
2508 work->options = hold_options;
2509 return;
2510 }
2511 /* ARM template? (Also handles HP cfront extensions) */
2512 else if (arm_pt (work, *mangled, n, &p, &args))
2513 {
2514 int hold_options;
2515 string type_str;
2516
2517 string_init (&arg);
2518 string_appendn (declp, *mangled, p - *mangled);
2519 if (work->temp_start == -1) /* non-recursive call */
2520 work->temp_start = declp->p - declp->b;
2521
2522 /* We want to unconditionally demangle parameter types in
2523 template parameters. */
2524 hold_options = work->options;
2525 work->options |= DMGL_PARAMS;
2526
2527 string_append (declp, "<");
2528 /* should do error checking here */
2529 while (args < e) {
2530 string_delete (&arg);
2531
2532 /* Check for type or literal here */
2533 switch (*args)
2534 {
2535 /* HP cfront extensions to ARM for template args */
2536 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2537 /* FIXME: We handle only numeric literals for HP cfront */
2538 case 'X':
2539 /* A typed constant value follows */
2540 args++;
2541 if (!do_type (work, &args, &type_str))
2542 goto cfront_template_args_done;
2543 string_append (&arg, "(");
2544 string_appends (&arg, &type_str);
2545 string_delete (&type_str);
2546 string_append (&arg, ")");
2547 if (*args != 'L')
2548 goto cfront_template_args_done;
2549 args++;
2550 /* Now snarf a literal value following 'L' */
2551 if (!snarf_numeric_literal (&args, &arg))
2552 goto cfront_template_args_done;
2553 break;
2554
2555 case 'L':
2556 /* Snarf a literal following 'L' */
2557 args++;
2558 if (!snarf_numeric_literal (&args, &arg))
2559 goto cfront_template_args_done;
2560 break;
2561 default:
2562 /* Not handling other HP cfront stuff */
2563 {
2564 const char* old_args = args;
2565 if (!do_type (work, &args, &arg))
2566 goto cfront_template_args_done;
2567
2568 /* Fail if we didn't make any progress: prevent infinite loop. */
2569 if (args == old_args)
2570 {
2571 work->options = hold_options;
2572 return;
2573 }
2574 }
2575 }
2576 string_appends (declp, &arg);
2577 string_append (declp, ",");
2578 }
2579 cfront_template_args_done:
2580 string_delete (&arg);
2581 if (args >= e)
2582 --declp->p; /* remove extra comma */
2583 string_append (declp, ">");
2584 work->options = hold_options;
2585 }
2586 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2587 && (*mangled)[9] == 'N'
2588 && (*mangled)[8] == (*mangled)[10]
2589 && strchr (cplus_markers, (*mangled)[8]))
2590 {
2591 /* A member of the anonymous namespace. */
2592 string_append (declp, "{anonymous}");
2593 }
2594 else
2595 {
2596 if (work->temp_start == -1) /* non-recursive call only */
2597 work->temp_start = 0; /* disable in recursive calls */
2598 string_appendn (declp, *mangled, n);
2599 }
2600 *mangled += n;
2601 }
2602
2603 /* Extract a class name, possibly a template with arguments, from the
2604 mangled string; qualifiers, local class indicators, etc. have
2605 already been dealt with */
2606
2607 static int
2608 demangle_class_name (struct work_stuff *work, const char **mangled,
2609 string *declp)
2610 {
2611 int n;
2612 int success = 0;
2613
2614 n = consume_count (mangled);
2615 if (n == -1)
2616 return 0;
2617 if ((int) strlen (*mangled) >= n)
2618 {
2619 demangle_arm_hp_template (work, mangled, n, declp);
2620 success = 1;
2621 }
2622
2623 return (success);
2624 }
2625
2626 /*
2627
2628 LOCAL FUNCTION
2629
2630 demangle_class -- demangle a mangled class sequence
2631
2632 SYNOPSIS
2633
2634 static int
2635 demangle_class (struct work_stuff *work, const char **mangled,
2636 strint *declp)
2637
2638 DESCRIPTION
2639
2640 DECLP points to the buffer into which demangling is being done.
2641
2642 *MANGLED points to the current token to be demangled. On input,
2643 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2644 On exit, it points to the next token after the mangled class on
2645 success, or the first unconsumed token on failure.
2646
2647 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2648 we are demangling a constructor or destructor. In this case
2649 we prepend "class::class" or "class::~class" to DECLP.
2650
2651 Otherwise, we prepend "class::" to the current DECLP.
2652
2653 Reset the constructor/destructor flags once they have been
2654 "consumed". This allows demangle_class to be called later during
2655 the same demangling, to do normal class demangling.
2656
2657 Returns 1 if demangling is successful, 0 otherwise.
2658
2659 */
2660
2661 static int
2662 demangle_class (struct work_stuff *work, const char **mangled, string *declp)
2663 {
2664 int success = 0;
2665 int btype;
2666 string class_name;
2667 char *save_class_name_end = 0;
2668
2669 string_init (&class_name);
2670 btype = register_Btype (work);
2671 if (demangle_class_name (work, mangled, &class_name))
2672 {
2673 save_class_name_end = class_name.p;
2674 if ((work->constructor & 1) || (work->destructor & 1))
2675 {
2676 /* adjust so we don't include template args */
2677 if (work->temp_start && (work->temp_start != -1))
2678 {
2679 class_name.p = class_name.b + work->temp_start;
2680 }
2681 string_prepends (declp, &class_name);
2682 if (work -> destructor & 1)
2683 {
2684 string_prepend (declp, "~");
2685 work -> destructor -= 1;
2686 }
2687 else
2688 {
2689 work -> constructor -= 1;
2690 }
2691 }
2692 class_name.p = save_class_name_end;
2693 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2694 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2695 string_prepend (declp, SCOPE_STRING (work));
2696 string_prepends (declp, &class_name);
2697 success = 1;
2698 }
2699 string_delete (&class_name);
2700 return (success);
2701 }
2702
2703
2704 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2705 the rightmost guess.
2706
2707 Find the correct "__"-sequence where the function name ends and the
2708 signature starts, which is ambiguous with GNU mangling.
2709 Call demangle_signature here, so we can make sure we found the right
2710 one; *mangled will be consumed so caller will not make further calls to
2711 demangle_signature. */
2712
2713 static int
2714 iterate_demangle_function (struct work_stuff *work, const char **mangled,
2715 string *declp, const char *scan)
2716 {
2717 const char *mangle_init = *mangled;
2718 int success = 0;
2719 string decl_init;
2720 struct work_stuff work_init;
2721
2722 if (*(scan + 2) == '\0')
2723 return 0;
2724
2725 /* Do not iterate for some demangling modes, or if there's only one
2726 "__"-sequence. This is the normal case. */
2727 if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2728 || strstr (scan + 2, "__") == NULL)
2729 return demangle_function_name (work, mangled, declp, scan);
2730
2731 /* Save state so we can restart if the guess at the correct "__" was
2732 wrong. */
2733 string_init (&decl_init);
2734 string_appends (&decl_init, declp);
2735 memset (&work_init, 0, sizeof work_init);
2736 work_stuff_copy_to_from (&work_init, work);
2737
2738 /* Iterate over occurrences of __, allowing names and types to have a
2739 "__" sequence in them. We must start with the first (not the last)
2740 occurrence, since "__" most often occur between independent mangled
2741 parts, hence starting at the last occurence inside a signature
2742 might get us a "successful" demangling of the signature. */
2743
2744 while (scan[2])
2745 {
2746 if (demangle_function_name (work, mangled, declp, scan))
2747 {
2748 success = demangle_signature (work, mangled, declp);
2749 if (success)
2750 break;
2751 }
2752
2753 /* Reset demangle state for the next round. */
2754 *mangled = mangle_init;
2755 string_clear (declp);
2756 string_appends (declp, &decl_init);
2757 work_stuff_copy_to_from (work, &work_init);
2758
2759 /* Leave this underscore-sequence. */
2760 scan += 2;
2761
2762 /* Scan for the next "__" sequence. */
2763 while (*scan && (scan[0] != '_' || scan[1] != '_'))
2764 scan++;
2765
2766 /* Move to last "__" in this sequence. */
2767 while (*scan && *scan == '_')
2768 scan++;
2769 scan -= 2;
2770 }
2771
2772 /* Delete saved state. */
2773 delete_work_stuff (&work_init);
2774 string_delete (&decl_init);
2775
2776 return success;
2777 }
2778
2779 /*
2780
2781 LOCAL FUNCTION
2782
2783 demangle_prefix -- consume the mangled name prefix and find signature
2784
2785 SYNOPSIS
2786
2787 static int
2788 demangle_prefix (struct work_stuff *work, const char **mangled,
2789 string *declp);
2790
2791 DESCRIPTION
2792
2793 Consume and demangle the prefix of the mangled name.
2794 While processing the function name root, arrange to call
2795 demangle_signature if the root is ambiguous.
2796
2797 DECLP points to the string buffer into which demangled output is
2798 placed. On entry, the buffer is empty. On exit it contains
2799 the root function name, the demangled operator name, or in some
2800 special cases either nothing or the completely demangled result.
2801
2802 MANGLED points to the current pointer into the mangled name. As each
2803 token of the mangled name is consumed, it is updated. Upon entry
2804 the current mangled name pointer points to the first character of
2805 the mangled name. Upon exit, it should point to the first character
2806 of the signature if demangling was successful, or to the first
2807 unconsumed character if demangling of the prefix was unsuccessful.
2808
2809 Returns 1 on success, 0 otherwise.
2810 */
2811
2812 static int
2813 demangle_prefix (struct work_stuff *work, const char **mangled,
2814 string *declp)
2815 {
2816 int success = 1;
2817 const char *scan;
2818 int i;
2819
2820 if (strlen(*mangled) > 6
2821 && (strncmp(*mangled, "_imp__", 6) == 0
2822 || strncmp(*mangled, "__imp_", 6) == 0))
2823 {
2824 /* it's a symbol imported from a PE dynamic library. Check for both
2825 new style prefix _imp__ and legacy __imp_ used by older versions
2826 of dlltool. */
2827 (*mangled) += 6;
2828 work->dllimported = 1;
2829 }
2830 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2831 {
2832 char *marker = strchr (cplus_markers, (*mangled)[8]);
2833 if (marker != NULL && *marker == (*mangled)[10])
2834 {
2835 if ((*mangled)[9] == 'D')
2836 {
2837 /* it's a GNU global destructor to be executed at program exit */
2838 (*mangled) += 11;
2839 work->destructor = 2;
2840 if (gnu_special (work, mangled, declp))
2841 return success;
2842 }
2843 else if ((*mangled)[9] == 'I')
2844 {
2845 /* it's a GNU global constructor to be executed at program init */
2846 (*mangled) += 11;
2847 work->constructor = 2;
2848 if (gnu_special (work, mangled, declp))
2849 return success;
2850 }
2851 }
2852 }
2853 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2854 {
2855 /* it's a ARM global destructor to be executed at program exit */
2856 (*mangled) += 7;
2857 work->destructor = 2;
2858 }
2859 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2860 {
2861 /* it's a ARM global constructor to be executed at program initial */
2862 (*mangled) += 7;
2863 work->constructor = 2;
2864 }
2865
2866 /* This block of code is a reduction in strength time optimization
2867 of:
2868 scan = strstr (*mangled, "__"); */
2869
2870 {
2871 scan = *mangled;
2872
2873 do {
2874 scan = strchr (scan, '_');
2875 } while (scan != NULL && *++scan != '_');
2876
2877 if (scan != NULL) --scan;
2878 }
2879
2880 if (scan != NULL)
2881 {
2882 /* We found a sequence of two or more '_', ensure that we start at
2883 the last pair in the sequence. */
2884 i = strspn (scan, "_");
2885 if (i > 2)
2886 {
2887 scan += (i - 2);
2888 }
2889 }
2890
2891 if (scan == NULL)
2892 {
2893 success = 0;
2894 }
2895 else if (work -> static_type)
2896 {
2897 if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2898 {
2899 success = 0;
2900 }
2901 }
2902 else if ((scan == *mangled)
2903 && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2904 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2905 {
2906 /* The ARM says nothing about the mangling of local variables.
2907 But cfront mangles local variables by prepending __<nesting_level>
2908 to them. As an extension to ARM demangling we handle this case. */
2909 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2910 && ISDIGIT ((unsigned char)scan[2]))
2911 {
2912 *mangled = scan + 2;
2913 consume_count (mangled);
2914 string_append (declp, *mangled);
2915 *mangled += strlen (*mangled);
2916 success = 1;
2917 }
2918 else
2919 {
2920 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2921 names like __Q2_3foo3bar for nested type names. So don't accept
2922 this style of constructor for cfront demangling. A GNU
2923 style member-template constructor starts with 'H'. */
2924 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2925 work -> constructor += 1;
2926 *mangled = scan + 2;
2927 }
2928 }
2929 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2930 {
2931 /* Cfront-style parameterized type. Handled later as a signature. */
2932 success = 1;
2933
2934 /* ARM template? */
2935 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2936 }
2937 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2938 || (scan[2] == 'p' && scan[3] == 's')
2939 || (scan[2] == 'p' && scan[3] == 't')))
2940 {
2941 /* EDG-style parameterized type. Handled later as a signature. */
2942 success = 1;
2943
2944 /* EDG template? */
2945 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2946 }
2947 else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2948 && (scan[2] != 't'))
2949 {
2950 /* Mangled name starts with "__". Skip over any leading '_' characters,
2951 then find the next "__" that separates the prefix from the signature.
2952 */
2953 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2954 || (arm_special (mangled, declp) == 0))
2955 {
2956 while (*scan == '_')
2957 {
2958 scan++;
2959 }
2960 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2961 {
2962 /* No separator (I.E. "__not_mangled"), or empty signature
2963 (I.E. "__not_mangled_either__") */
2964 success = 0;
2965 }
2966 else
2967 return iterate_demangle_function (work, mangled, declp, scan);
2968 }
2969 }
2970 else if (*(scan + 2) != '\0')
2971 {
2972 /* Mangled name does not start with "__" but does have one somewhere
2973 in there with non empty stuff after it. Looks like a global
2974 function name. Iterate over all "__":s until the right
2975 one is found. */
2976 return iterate_demangle_function (work, mangled, declp, scan);
2977 }
2978 else
2979 {
2980 /* Doesn't look like a mangled name */
2981 success = 0;
2982 }
2983
2984 if (!success && (work->constructor == 2 || work->destructor == 2))
2985 {
2986 string_append (declp, *mangled);
2987 *mangled += strlen (*mangled);
2988 success = 1;
2989 }
2990 return (success);
2991 }
2992
2993 /*
2994
2995 LOCAL FUNCTION
2996
2997 gnu_special -- special handling of gnu mangled strings
2998
2999 SYNOPSIS
3000
3001 static int
3002 gnu_special (struct work_stuff *work, const char **mangled,
3003 string *declp);
3004
3005
3006 DESCRIPTION
3007
3008 Process some special GNU style mangling forms that don't fit
3009 the normal pattern. For example:
3010
3011 _$_3foo (destructor for class foo)
3012 _vt$foo (foo virtual table)
3013 _vt$foo$bar (foo::bar virtual table)
3014 __vt_foo (foo virtual table, new style with thunks)
3015 _3foo$varname (static data member)
3016 _Q22rs2tu$vw (static data member)
3017 __t6vector1Zii (constructor with template)
3018 __thunk_4__$_7ostream (virtual function thunk)
3019 */
3020
3021 static int
3022 gnu_special (struct work_stuff *work, const char **mangled, string *declp)
3023 {
3024 int n;
3025 int success = 1;
3026 const char *p;
3027
3028 if ((*mangled)[0] == '_' && (*mangled)[1] != '\0'
3029 && strchr (cplus_markers, (*mangled)[1]) != NULL
3030 && (*mangled)[2] == '_')
3031 {
3032 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
3033 (*mangled) += 3;
3034 work -> destructor += 1;
3035 }
3036 else if ((*mangled)[0] == '_'
3037 && (((*mangled)[1] == '_'
3038 && (*mangled)[2] == 'v'
3039 && (*mangled)[3] == 't'
3040 && (*mangled)[4] == '_')
3041 || ((*mangled)[1] == 'v'
3042 && (*mangled)[2] == 't' && (*mangled)[3] != '\0'
3043 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
3044 {
3045 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
3046 and create the decl. Note that we consume the entire mangled
3047 input string, which means that demangle_signature has no work
3048 to do. */
3049 if ((*mangled)[2] == 'v')
3050 (*mangled) += 5; /* New style, with thunks: "__vt_" */
3051 else
3052 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
3053 while (**mangled != '\0')
3054 {
3055 switch (**mangled)
3056 {
3057 case 'Q':
3058 case 'K':
3059 success = demangle_qualified (work, mangled, declp, 0, 1);
3060 break;
3061 case 't':
3062 success = demangle_template (work, mangled, declp, 0, 1,
3063 1);
3064 break;
3065 default:
3066 if (ISDIGIT((unsigned char)*mangled[0]))
3067 {
3068 n = consume_count(mangled);
3069 /* We may be seeing a too-large size, or else a
3070 ".<digits>" indicating a static local symbol. In
3071 any case, declare victory and move on; *don't* try
3072 to use n to allocate. */
3073 if (n > (int) strlen (*mangled))
3074 {
3075 success = 1;
3076 break;
3077 }
3078 else if (n == -1)
3079 {
3080 success = 0;
3081 break;
3082 }
3083 }
3084 else
3085 {
3086 n = strcspn (*mangled, cplus_markers);
3087 }
3088 string_appendn (declp, *mangled, n);
3089 (*mangled) += n;
3090 }
3091
3092 p = strpbrk (*mangled, cplus_markers);
3093 if (success && ((p == NULL) || (p == *mangled)))
3094 {
3095 if (p != NULL)
3096 {
3097 string_append (declp, SCOPE_STRING (work));
3098 (*mangled)++;
3099 }
3100 }
3101 else
3102 {
3103 success = 0;
3104 break;
3105 }
3106 }
3107 if (success)
3108 string_append (declp, " virtual table");
3109 }
3110 else if ((*mangled)[0] == '_'
3111 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
3112 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
3113 {
3114 /* static data member, "_3foo$varname" for example */
3115 (*mangled)++;
3116 switch (**mangled)
3117 {
3118 case 'Q':
3119 case 'K':
3120 success = demangle_qualified (work, mangled, declp, 0, 1);
3121 break;
3122 case 't':
3123 success = demangle_template (work, mangled, declp, 0, 1, 1);
3124 break;
3125 default:
3126 n = consume_count (mangled);
3127 if (n < 0 || n > (long) strlen (*mangled))
3128 {
3129 success = 0;
3130 break;
3131 }
3132
3133 if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
3134 && (*mangled)[9] == 'N'
3135 && (*mangled)[8] == (*mangled)[10]
3136 && strchr (cplus_markers, (*mangled)[8]))
3137 {
3138 /* A member of the anonymous namespace. There's information
3139 about what identifier or filename it was keyed to, but
3140 it's just there to make the mangled name unique; we just
3141 step over it. */
3142 string_append (declp, "{anonymous}");
3143 (*mangled) += n;
3144
3145 /* Now p points to the marker before the N, so we need to
3146 update it to the first marker after what we consumed. */
3147 p = strpbrk (*mangled, cplus_markers);
3148 break;
3149 }
3150
3151 string_appendn (declp, *mangled, n);
3152 (*mangled) += n;
3153 }
3154 if (success && (p == *mangled))
3155 {
3156 /* Consumed everything up to the cplus_marker, append the
3157 variable name. */
3158 (*mangled)++;
3159 string_append (declp, SCOPE_STRING (work));
3160 n = strlen (*mangled);
3161 string_appendn (declp, *mangled, n);
3162 (*mangled) += n;
3163 }
3164 else
3165 {
3166 success = 0;
3167 }
3168 }
3169 else if (strncmp (*mangled, "__thunk_", 8) == 0)
3170 {
3171 int delta;
3172
3173 (*mangled) += 8;
3174 delta = consume_count (mangled);
3175 if (delta == -1)
3176 success = 0;
3177 else
3178 {
3179 char *method = internal_cplus_demangle (work, ++*mangled);
3180
3181 if (method)
3182 {
3183 char buf[50];
3184 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
3185 string_append (declp, buf);
3186 string_append (declp, method);
3187 free (method);
3188 n = strlen (*mangled);
3189 (*mangled) += n;
3190 }
3191 else
3192 {
3193 success = 0;
3194 }
3195 }
3196 }
3197 else if (strncmp (*mangled, "__t", 3) == 0
3198 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
3199 {
3200 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
3201 (*mangled) += 4;
3202 switch (**mangled)
3203 {
3204 case 'Q':
3205 case 'K':
3206 success = demangle_qualified (work, mangled, declp, 0, 1);
3207 break;
3208 case 't':
3209 success = demangle_template (work, mangled, declp, 0, 1, 1);
3210 break;
3211 default:
3212 success = do_type (work, mangled, declp);
3213 break;
3214 }
3215 if (success && **mangled != '\0')
3216 success = 0;
3217 if (success)
3218 string_append (declp, p);
3219 }
3220 else
3221 {
3222 success = 0;
3223 }
3224 return (success);
3225 }
3226
3227 static void
3228 recursively_demangle(struct work_stuff *work, const char **mangled,
3229 string *result, int namelength)
3230 {
3231 char * recurse = (char *)NULL;
3232 char * recurse_dem = (char *)NULL;
3233
3234 recurse = XNEWVEC (char, namelength + 1);
3235 memcpy (recurse, *mangled, namelength);
3236 recurse[namelength] = '\000';
3237
3238 recurse_dem = cplus_demangle (recurse, work->options);
3239
3240 if (recurse_dem)
3241 {
3242 string_append (result, recurse_dem);
3243 free (recurse_dem);
3244 }
3245 else
3246 {
3247 string_appendn (result, *mangled, namelength);
3248 }
3249 free (recurse);
3250 *mangled += namelength;
3251 }
3252
3253 /*
3254
3255 LOCAL FUNCTION
3256
3257 arm_special -- special handling of ARM/lucid mangled strings
3258
3259 SYNOPSIS
3260
3261 static int
3262 arm_special (const char **mangled,
3263 string *declp);
3264
3265
3266 DESCRIPTION
3267
3268 Process some special ARM style mangling forms that don't fit
3269 the normal pattern. For example:
3270
3271 __vtbl__3foo (foo virtual table)
3272 __vtbl__3foo__3bar (bar::foo virtual table)
3273
3274 */
3275
3276 static int
3277 arm_special (const char **mangled, string *declp)
3278 {
3279 int n;
3280 int success = 1;
3281 const char *scan;
3282
3283 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3284 {
3285 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3286 and create the decl. Note that we consume the entire mangled
3287 input string, which means that demangle_signature has no work
3288 to do. */
3289 scan = *mangled + ARM_VTABLE_STRLEN;
3290 while (*scan != '\0') /* first check it can be demangled */
3291 {
3292 n = consume_count (&scan);
3293 if (n == -1)
3294 {
3295 return (0); /* no good */
3296 }
3297 scan += n;
3298 if (scan[0] == '_' && scan[1] == '_')
3299 {
3300 scan += 2;
3301 }
3302 }
3303 (*mangled) += ARM_VTABLE_STRLEN;
3304 while (**mangled != '\0')
3305 {
3306 n = consume_count (mangled);
3307 if (n == -1
3308 || n > (long) strlen (*mangled))
3309 return 0;
3310 string_prependn (declp, *mangled, n);
3311 (*mangled) += n;
3312 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3313 {
3314 string_prepend (declp, "::");
3315 (*mangled) += 2;
3316 }
3317 }
3318 string_append (declp, " virtual table");
3319 }
3320 else
3321 {
3322 success = 0;
3323 }
3324 return (success);
3325 }
3326
3327 /*
3328
3329 LOCAL FUNCTION
3330
3331 demangle_qualified -- demangle 'Q' qualified name strings
3332
3333 SYNOPSIS
3334
3335 static int
3336 demangle_qualified (struct work_stuff *, const char *mangled,
3337 string *result, int isfuncname, int append);
3338
3339 DESCRIPTION
3340
3341 Demangle a qualified name, such as "Q25Outer5Inner" which is
3342 the mangled form of "Outer::Inner". The demangled output is
3343 prepended or appended to the result string according to the
3344 state of the append flag.
3345
3346 If isfuncname is nonzero, then the qualified name we are building
3347 is going to be used as a member function name, so if it is a
3348 constructor or destructor function, append an appropriate
3349 constructor or destructor name. I.E. for the above example,
3350 the result for use as a constructor is "Outer::Inner::Inner"
3351 and the result for use as a destructor is "Outer::Inner::~Inner".
3352
3353 BUGS
3354
3355 Numeric conversion is ASCII dependent (FIXME).
3356
3357 */
3358
3359 static int
3360 demangle_qualified (struct work_stuff *work, const char **mangled,
3361 string *result, int isfuncname, int append)
3362 {
3363 int qualifiers = 0;
3364 int success = 1;
3365 char num[2];
3366 string temp;
3367 string last_name;
3368 int bindex = register_Btype (work);
3369
3370 /* We only make use of ISFUNCNAME if the entity is a constructor or
3371 destructor. */
3372 isfuncname = (isfuncname
3373 && ((work->constructor & 1) || (work->destructor & 1)));
3374
3375 string_init (&temp);
3376 string_init (&last_name);
3377
3378 if ((*mangled)[0] == 'K')
3379 {
3380 /* Squangling qualified name reuse */
3381 int idx;
3382 (*mangled)++;
3383 idx = consume_count_with_underscores (mangled);
3384 if (idx == -1 || idx >= work -> numk)
3385 success = 0;
3386 else
3387 string_append (&temp, work -> ktypevec[idx]);
3388 }
3389 else
3390 switch ((*mangled)[1])
3391 {
3392 case '_':
3393 /* GNU mangled name with more than 9 classes. The count is preceded
3394 by an underscore (to distinguish it from the <= 9 case) and followed
3395 by an underscore. */
3396 (*mangled)++;
3397 qualifiers = consume_count_with_underscores (mangled);
3398 if (qualifiers == -1)
3399 success = 0;
3400 break;
3401
3402 case '1':
3403 case '2':
3404 case '3':
3405 case '4':
3406 case '5':
3407 case '6':
3408 case '7':
3409 case '8':
3410 case '9':
3411 /* The count is in a single digit. */
3412 num[0] = (*mangled)[1];
3413 num[1] = '\0';
3414 qualifiers = atoi (num);
3415
3416 /* If there is an underscore after the digit, skip it. This is
3417 said to be for ARM-qualified names, but the ARM makes no
3418 mention of such an underscore. Perhaps cfront uses one. */
3419 if ((*mangled)[2] == '_')
3420 {
3421 (*mangled)++;
3422 }
3423 (*mangled) += 2;
3424 break;
3425
3426 case '0':
3427 default:
3428 success = 0;
3429 }
3430
3431 if (!success)
3432 return success;
3433
3434 /* Pick off the names and collect them in the temp buffer in the order
3435 in which they are found, separated by '::'. */
3436
3437 while (qualifiers-- > 0)
3438 {
3439 int remember_K = 1;
3440 string_clear (&last_name);
3441
3442 if (*mangled[0] == '_')
3443 (*mangled)++;
3444
3445 if (*mangled[0] == 't')
3446 {
3447 /* Here we always append to TEMP since we will want to use
3448 the template name without the template parameters as a
3449 constructor or destructor name. The appropriate
3450 (parameter-less) value is returned by demangle_template
3451 in LAST_NAME. We do not remember the template type here,
3452 in order to match the G++ mangling algorithm. */
3453 success = demangle_template(work, mangled, &temp,
3454 &last_name, 1, 0);
3455 if (!success)
3456 break;
3457 }
3458 else if (*mangled[0] == 'K')
3459 {
3460 int idx;
3461 (*mangled)++;
3462 idx = consume_count_with_underscores (mangled);
3463 if (idx == -1 || idx >= work->numk)
3464 success = 0;
3465 else
3466 string_append (&temp, work->ktypevec[idx]);
3467 remember_K = 0;
3468
3469 if (!success) break;
3470 }
3471 else
3472 {
3473 if (EDG_DEMANGLING)
3474 {
3475 int namelength;
3476 /* Now recursively demangle the qualifier
3477 * This is necessary to deal with templates in
3478 * mangling styles like EDG */
3479 namelength = consume_count (mangled);
3480 if (namelength == -1)
3481 {
3482 success = 0;
3483 break;
3484 }
3485 recursively_demangle(work, mangled, &temp, namelength);
3486 }
3487 else
3488 {
3489 string_delete (&last_name);
3490 success = do_type (work, mangled, &last_name);
3491 if (!success)
3492 break;
3493 string_appends (&temp, &last_name);
3494 }
3495 }
3496
3497 if (remember_K)
3498 remember_Ktype (work, temp.b, LEN_STRING (&temp));
3499
3500 if (qualifiers > 0)
3501 string_append (&temp, SCOPE_STRING (work));
3502 }
3503
3504 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3505
3506 /* If we are using the result as a function name, we need to append
3507 the appropriate '::' separated constructor or destructor name.
3508 We do this here because this is the most convenient place, where
3509 we already have a pointer to the name and the length of the name. */
3510
3511 if (isfuncname)
3512 {
3513 string_append (&temp, SCOPE_STRING (work));
3514 if (work -> destructor & 1)
3515 string_append (&temp, "~");
3516 string_appends (&temp, &last_name);
3517 }
3518
3519 /* Now either prepend the temp buffer to the result, or append it,
3520 depending upon the state of the append flag. */
3521
3522 if (append)
3523 string_appends (result, &temp);
3524 else
3525 {
3526 if (!STRING_EMPTY (result))
3527 string_append (&temp, SCOPE_STRING (work));
3528 string_prepends (result, &temp);
3529 }
3530
3531 string_delete (&last_name);
3532 string_delete (&temp);
3533 return (success);
3534 }
3535
3536 /*
3537
3538 LOCAL FUNCTION
3539
3540 get_count -- convert an ascii count to integer, consuming tokens
3541
3542 SYNOPSIS
3543
3544 static int
3545 get_count (const char **type, int *count)
3546
3547 DESCRIPTION
3548
3549 Assume that *type points at a count in a mangled name; set
3550 *count to its value, and set *type to the next character after
3551 the count. There are some weird rules in effect here.
3552
3553 If *type does not point at a string of digits, return zero.
3554
3555 If *type points at a string of digits followed by an
3556 underscore, set *count to their value as an integer, advance
3557 *type to point *after the underscore, and return 1.
3558
3559 If *type points at a string of digits not followed by an
3560 underscore, consume only the first digit. Set *count to its
3561 value as an integer, leave *type pointing after that digit,
3562 and return 1.
3563
3564 The excuse for this odd behavior: in the ARM and HP demangling
3565 styles, a type can be followed by a repeat count of the form
3566 `Nxy', where:
3567
3568 `x' is a single digit specifying how many additional copies
3569 of the type to append to the argument list, and
3570
3571 `y' is one or more digits, specifying the zero-based index of
3572 the first repeated argument in the list. Yes, as you're
3573 unmangling the name you can figure this out yourself, but
3574 it's there anyway.
3575
3576 So, for example, in `bar__3fooFPiN51', the first argument is a
3577 pointer to an integer (`Pi'), and then the next five arguments
3578 are the same (`N5'), and the first repeat is the function's
3579 second argument (`1').
3580 */
3581
3582 static int
3583 get_count (const char **type, int *count)
3584 {
3585 const char *p;
3586 int n;
3587
3588 if (!ISDIGIT ((unsigned char)**type))
3589 return (0);
3590 else
3591 {
3592 *count = **type - '0';
3593 (*type)++;
3594 if (ISDIGIT ((unsigned char)**type))
3595 {
3596 p = *type;
3597 n = *count;
3598 do
3599 {
3600 n *= 10;
3601 n += *p - '0';
3602 p++;
3603 }
3604 while (ISDIGIT ((unsigned char)*p));
3605 if (*p == '_')
3606 {
3607 *type = p + 1;
3608 *count = n;
3609 }
3610 }
3611 }
3612 return (1);
3613 }
3614
3615 /* RESULT will be initialised here; it will be freed on failure. The
3616 value returned is really a type_kind_t. */
3617
3618 static int
3619 do_type (struct work_stuff *work, const char **mangled, string *result)
3620 {
3621 int n;
3622 int i;
3623 int is_proctypevec;
3624 int done;
3625 int success;
3626 string decl;
3627 const char *remembered_type;
3628 int type_quals;
3629 type_kind_t tk = tk_none;
3630
3631 string_init (&decl);
3632 string_init (result);
3633
3634 done = 0;
3635 success = 1;
3636 is_proctypevec = 0;
3637 while (success && !done)
3638 {
3639 int member;
3640 switch (**mangled)
3641 {
3642
3643 /* A pointer type */
3644 case 'P':
3645 case 'p':
3646 (*mangled)++;
3647 if (! (work -> options & DMGL_JAVA))
3648 string_prepend (&decl, "*");
3649 if (tk == tk_none)
3650 tk = tk_pointer;
3651 break;
3652
3653 /* A reference type */
3654 case 'R':
3655 (*mangled)++;
3656 string_prepend (&decl, "&");
3657 if (tk == tk_none)
3658 tk = tk_reference;
3659 break;
3660
3661 /* An rvalue reference type */
3662 case 'O':
3663 (*mangled)++;
3664 string_prepend (&decl, "&&");
3665 if (tk == tk_none)
3666 tk = tk_rvalue_reference;
3667 break;
3668
3669 /* An array */
3670 case 'A':
3671 {
3672 ++(*mangled);
3673 if (!STRING_EMPTY (&decl)
3674 && (decl.b[0] == '*' || decl.b[0] == '&'))
3675 {
3676 string_prepend (&decl, "(");
3677 string_append (&decl, ")");
3678 }
3679 string_append (&decl, "[");
3680 if (**mangled != '_')
3681 success = demangle_template_value_parm (work, mangled, &decl,
3682 tk_integral);
3683 if (**mangled == '_')
3684 ++(*mangled);
3685 string_append (&decl, "]");
3686 break;
3687 }
3688
3689 /* A back reference to a previously seen type */
3690 case 'T':
3691 (*mangled)++;
3692 if (!get_count (mangled, &n) || n < 0 || n >= work -> ntypes)
3693 {
3694 success = 0;
3695 }
3696 else
3697 for (i = 0; i < work->nproctypes; i++)
3698 if (work -> proctypevec [i] == n)
3699 success = 0;
3700
3701 if (success)
3702 {
3703 is_proctypevec = 1;
3704 push_processed_type (work, n);
3705 remembered_type = work->typevec[n];
3706 mangled = &remembered_type;
3707 }
3708 break;
3709
3710 /* A function */
3711 case 'F':
3712 (*mangled)++;
3713 if (!STRING_EMPTY (&decl)
3714 && (decl.b[0] == '*' || decl.b[0] == '&'))
3715 {
3716 string_prepend (&decl, "(");
3717 string_append (&decl, ")");
3718 }
3719 /* After picking off the function args, we expect to either find the
3720 function return type (preceded by an '_') or the end of the
3721 string. */
3722 if (!demangle_nested_args (work, mangled, &decl)
3723 || (**mangled != '_' && **mangled != '\0'))
3724 {
3725 success = 0;
3726 break;
3727 }
3728 if (success && (**mangled == '_'))
3729 (*mangled)++;
3730 break;
3731
3732 case 'M':
3733 {
3734 type_quals = TYPE_UNQUALIFIED;
3735
3736 member = **mangled == 'M';
3737 (*mangled)++;
3738
3739 string_append (&decl, ")");
3740
3741 /* We don't need to prepend `::' for a qualified name;
3742 demangle_qualified will do that for us. */
3743 if (**mangled != 'Q')
3744 string_prepend (&decl, SCOPE_STRING (work));
3745
3746 if (ISDIGIT ((unsigned char)**mangled))
3747 {
3748 n = consume_count (mangled);
3749 if (n == -1
3750 || (int) strlen (*mangled) < n)
3751 {
3752 success = 0;
3753 break;
3754 }
3755 string_prependn (&decl, *mangled, n);
3756 *mangled += n;
3757 }
3758 else if (**mangled == 'X' || **mangled == 'Y')
3759 {
3760 string temp;
3761 do_type (work, mangled, &temp);
3762 string_prepends (&decl, &temp);
3763 string_delete (&temp);
3764 }
3765 else if (**mangled == 't')
3766 {
3767 string temp;
3768 string_init (&temp);
3769 success = demangle_template (work, mangled, &temp,
3770 NULL, 1, 1);
3771 if (success)
3772 {
3773 string_prependn (&decl, temp.b, temp.p - temp.b);
3774 string_delete (&temp);
3775 }
3776 else
3777 {
3778 string_delete (&temp);
3779 break;
3780 }
3781 }
3782 else if (**mangled == 'Q')
3783 {
3784 success = demangle_qualified (work, mangled, &decl,
3785 /*isfuncnam=*/0,
3786 /*append=*/0);
3787 if (!success)
3788 break;
3789 }
3790 else
3791 {
3792 success = 0;
3793 break;
3794 }
3795
3796 string_prepend (&decl, "(");
3797 if (member)
3798 {
3799 switch (**mangled)
3800 {
3801 case 'C':
3802 case 'V':
3803 case 'u':
3804 type_quals |= code_for_qualifier (**mangled);
3805 (*mangled)++;
3806 break;
3807
3808 default:
3809 break;
3810 }
3811
3812 if (*(*mangled) != 'F')
3813 {
3814 success = 0;
3815 break;
3816 }
3817 (*mangled)++;
3818 }
3819 if ((member && !demangle_nested_args (work, mangled, &decl))
3820 || **mangled != '_')
3821 {
3822 success = 0;
3823 break;
3824 }
3825 (*mangled)++;
3826 if (! PRINT_ANSI_QUALIFIERS)
3827 {
3828 break;
3829 }
3830 if (type_quals != TYPE_UNQUALIFIED)
3831 {
3832 APPEND_BLANK (&decl);
3833 string_append (&decl, qualifier_string (type_quals));
3834 }
3835 break;
3836 }
3837 case 'G':
3838 (*mangled)++;
3839 break;
3840
3841 case 'C':
3842 case 'V':
3843 case 'u':
3844 if (PRINT_ANSI_QUALIFIERS)
3845 {
3846 if (!STRING_EMPTY (&decl))
3847 string_prepend (&decl, " ");
3848
3849 string_prepend (&decl, demangle_qualifier (**mangled));
3850 }
3851 (*mangled)++;
3852 break;
3853 /*
3854 }
3855 */
3856
3857 /* fall through */
3858 default:
3859 done = 1;
3860 break;
3861 }
3862 }
3863
3864 if (success) switch (**mangled)
3865 {
3866 /* A qualified name, such as "Outer::Inner". */
3867 case 'Q':
3868 case 'K':
3869 {
3870 success = demangle_qualified (work, mangled, result, 0, 1);
3871 break;
3872 }
3873
3874 /* A back reference to a previously seen squangled type */
3875 case 'B':
3876 (*mangled)++;
3877 if (!get_count (mangled, &n) || n < 0 || n >= work -> numb)
3878 success = 0;
3879 else
3880 string_append (result, work->btypevec[n]);
3881 break;
3882
3883 case 'X':
3884 case 'Y':
3885 /* A template parm. We substitute the corresponding argument. */
3886 {
3887 int idx;
3888
3889 (*mangled)++;
3890 idx = consume_count_with_underscores (mangled);
3891
3892 if (idx == -1
3893 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3894 || consume_count_with_underscores (mangled) == -1)
3895 {
3896 success = 0;
3897 break;
3898 }
3899
3900 if (work->tmpl_argvec)
3901 string_append (result, work->tmpl_argvec[idx]);
3902 else
3903 string_append_template_idx (result, idx);
3904
3905 success = 1;
3906 }
3907 break;
3908
3909 default:
3910 success = demangle_fund_type (work, mangled, result);
3911 if (tk == tk_none)
3912 tk = (type_kind_t) success;
3913 break;
3914 }
3915
3916 if (success)
3917 {
3918 if (!STRING_EMPTY (&decl))
3919 {
3920 string_append (result, " ");
3921 string_appends (result, &decl);
3922 }
3923 }
3924 else
3925 string_delete (result);
3926 string_delete (&decl);
3927
3928 if (is_proctypevec)
3929 pop_processed_type (work);
3930
3931 if (success)
3932 /* Assume an integral type, if we're not sure. */
3933 return (int) ((tk == tk_none) ? tk_integral : tk);
3934 else
3935 return 0;
3936 }
3937
3938 /* Given a pointer to a type string that represents a fundamental type
3939 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3940 string in which the demangled output is being built in RESULT, and
3941 the WORK structure, decode the types and add them to the result.
3942
3943 For example:
3944
3945 "Ci" => "const int"
3946 "Sl" => "signed long"
3947 "CUs" => "const unsigned short"
3948
3949 The value returned is really a type_kind_t. */
3950
3951 static int
3952 demangle_fund_type (struct work_stuff *work,
3953 const char **mangled, string *result)
3954 {
3955 int done = 0;
3956 int success = 1;
3957 char buf[INTBUF_SIZE + 5 /* 'int%u_t' */];
3958 unsigned int dec = 0;
3959 type_kind_t tk = tk_integral;
3960
3961 /* First pick off any type qualifiers. There can be more than one. */
3962
3963 while (!done)
3964 {
3965 switch (**mangled)
3966 {
3967 case 'C':
3968 case 'V':
3969 case 'u':
3970 if (PRINT_ANSI_QUALIFIERS)
3971 {
3972 if (!STRING_EMPTY (result))
3973 string_prepend (result, " ");
3974 string_prepend (result, demangle_qualifier (**mangled));
3975 }
3976 (*mangled)++;
3977 break;
3978 case 'U':
3979 (*mangled)++;
3980 APPEND_BLANK (result);
3981 string_append (result, "unsigned");
3982 break;
3983 case 'S': /* signed char only */
3984 (*mangled)++;
3985 APPEND_BLANK (result);
3986 string_append (result, "signed");
3987 break;
3988 case 'J':
3989 (*mangled)++;
3990 APPEND_BLANK (result);
3991 string_append (result, "__complex");
3992 break;
3993 default:
3994 done = 1;
3995 break;
3996 }
3997 }
3998
3999 /* Now pick off the fundamental type. There can be only one. */
4000
4001 switch (**mangled)
4002 {
4003 case '\0':
4004 case '_':
4005 break;
4006 case 'v':
4007 (*mangled)++;
4008 APPEND_BLANK (result);
4009 string_append (result, "void");
4010 break;
4011 case 'x':
4012 (*mangled)++;
4013 APPEND_BLANK (result);
4014 string_append (result, "long long");
4015 break;
4016 case 'l':
4017 (*mangled)++;
4018 APPEND_BLANK (result);
4019 string_append (result, "long");
4020 break;
4021 case 'i':
4022 (*mangled)++;
4023 APPEND_BLANK (result);
4024 string_append (result, "int");
4025 break;
4026 case 's':
4027 (*mangled)++;
4028 APPEND_BLANK (result);
4029 string_append (result, "short");
4030 break;
4031 case 'b':
4032 (*mangled)++;
4033 APPEND_BLANK (result);
4034 string_append (result, "bool");
4035 tk = tk_bool;
4036 break;
4037 case 'c':
4038 (*mangled)++;
4039 APPEND_BLANK (result);
4040 string_append (result, "char");
4041 tk = tk_char;
4042 break;
4043 case 'w':
4044 (*mangled)++;
4045 APPEND_BLANK (result);
4046 string_append (result, "wchar_t");
4047 tk = tk_char;
4048 break;
4049 case 'r':
4050 (*mangled)++;
4051 APPEND_BLANK (result);
4052 string_append (result, "long double");
4053 tk = tk_real;
4054 break;
4055 case 'd':
4056 (*mangled)++;
4057 APPEND_BLANK (result);
4058 string_append (result, "double");
4059 tk = tk_real;
4060 break;
4061 case 'f':
4062 (*mangled)++;
4063 APPEND_BLANK (result);
4064 string_append (result, "float");
4065 tk = tk_real;
4066 break;
4067 case 'G':
4068 (*mangled)++;
4069 if (!ISDIGIT ((unsigned char)**mangled))
4070 {
4071 success = 0;
4072 break;
4073 }
4074 /* fall through */
4075 case 'I':
4076 (*mangled)++;
4077 if (**mangled == '_')
4078 {
4079 int i;
4080 (*mangled)++;
4081 for (i = 0;
4082 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
4083 (*mangled)++, i++)
4084 buf[i] = **mangled;
4085 if (**mangled != '_')
4086 {
4087 success = 0;
4088 break;
4089 }
4090 buf[i] = '\0';
4091 (*mangled)++;
4092 }
4093 else
4094 {
4095 strncpy (buf, *mangled, 2);
4096 buf[2] = '\0';
4097 *mangled += min (strlen (*mangled), 2);
4098 }
4099 sscanf (buf, "%x", &dec);
4100 sprintf (buf, "int%u_t", dec);
4101 APPEND_BLANK (result);
4102 string_append (result, buf);
4103 break;
4104
4105 /* fall through */
4106 /* An explicit type, such as "6mytype" or "7integer" */
4107 case '0':
4108 case '1':
4109 case '2':
4110 case '3':
4111 case '4':
4112 case '5':
4113 case '6':
4114 case '7':
4115 case '8':
4116 case '9':
4117 {
4118 int bindex = register_Btype (work);
4119 string btype;
4120 string_init (&btype);
4121 if (demangle_class_name (work, mangled, &btype)) {
4122 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
4123 APPEND_BLANK (result);
4124 string_appends (result, &btype);
4125 }
4126 else
4127 success = 0;
4128 string_delete (&btype);
4129 break;
4130 }
4131 case 't':
4132 {
4133 string btype;
4134 string_init (&btype);
4135 success = demangle_template (work, mangled, &btype, 0, 1, 1);
4136 string_appends (result, &btype);
4137 string_delete (&btype);
4138 break;
4139 }
4140 default:
4141 success = 0;
4142 break;
4143 }
4144
4145 return success ? ((int) tk) : 0;
4146 }
4147
4148
4149 /* Handle a template's value parameter for HP aCC (extension from ARM)
4150 **mangled points to 'S' or 'U' */
4151
4152 static int
4153 do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED,
4154 const char **mangled, string *result)
4155 {
4156 int unsigned_const;
4157
4158 if (**mangled != 'U' && **mangled != 'S')
4159 return 0;
4160
4161 unsigned_const = (**mangled == 'U');
4162
4163 (*mangled)++;
4164
4165 switch (**mangled)
4166 {
4167 case 'N':
4168 string_append (result, "-");
4169 /* fall through */
4170 case 'P':
4171 (*mangled)++;
4172 break;
4173 case 'M':
4174 /* special case for -2^31 */
4175 string_append (result, "-2147483648");
4176 (*mangled)++;
4177 return 1;
4178 default:
4179 return 0;
4180 }
4181
4182 /* We have to be looking at an integer now */
4183 if (!(ISDIGIT ((unsigned char)**mangled)))
4184 return 0;
4185
4186 /* We only deal with integral values for template
4187 parameters -- so it's OK to look only for digits */
4188 while (ISDIGIT ((unsigned char)**mangled))
4189 {
4190 char_str[0] = **mangled;
4191 string_append (result, char_str);
4192 (*mangled)++;
4193 }
4194
4195 if (unsigned_const)
4196 string_append (result, "U");
4197
4198 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4199 with L or LL suffixes. pai/1997-09-03 */
4200
4201 return 1; /* success */
4202 }
4203
4204 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4205 **mangled is pointing to the 'A' */
4206
4207 static int
4208 do_hpacc_template_literal (struct work_stuff *work, const char **mangled,
4209 string *result)
4210 {
4211 int literal_len = 0;
4212 char * recurse;
4213 char * recurse_dem;
4214
4215 if (**mangled != 'A')
4216 return 0;
4217
4218 (*mangled)++;
4219
4220 literal_len = consume_count (mangled);
4221
4222 if (literal_len <= 0
4223 || literal_len > (long) strlen (*mangled))
4224 return 0;
4225
4226 /* Literal parameters are names of arrays, functions, etc. and the
4227 canonical representation uses the address operator */
4228 string_append (result, "&");
4229
4230 /* Now recursively demangle the literal name */
4231 recurse = XNEWVEC (char, literal_len + 1);
4232 memcpy (recurse, *mangled, literal_len);
4233 recurse[literal_len] = '\000';
4234
4235 recurse_dem = cplus_demangle (recurse, work->options);
4236
4237 if (recurse_dem)
4238 {
4239 string_append (result, recurse_dem);
4240 free (recurse_dem);
4241 }
4242 else
4243 {
4244 string_appendn (result, *mangled, literal_len);
4245 }
4246 (*mangled) += literal_len;
4247 free (recurse);
4248
4249 return 1;
4250 }
4251
4252 static int
4253 snarf_numeric_literal (const char **args, string *arg)
4254 {
4255 if (**args == '-')
4256 {
4257 char_str[0] = '-';
4258 string_append (arg, char_str);
4259 (*args)++;
4260 }
4261 else if (**args == '+')
4262 (*args)++;
4263
4264 if (!ISDIGIT ((unsigned char)**args))
4265 return 0;
4266
4267 while (ISDIGIT ((unsigned char)**args))
4268 {
4269 char_str[0] = **args;
4270 string_append (arg, char_str);
4271 (*args)++;
4272 }
4273
4274 return 1;
4275 }
4276
4277 /* Demangle the next argument, given by MANGLED into RESULT, which
4278 *should be an uninitialized* string. It will be initialized here,
4279 and free'd should anything go wrong. */
4280
4281 static int
4282 do_arg (struct work_stuff *work, const char **mangled, string *result)
4283 {
4284 /* Remember where we started so that we can record the type, for
4285 non-squangling type remembering. */
4286 const char *start = *mangled;
4287
4288 string_init (result);
4289
4290 if (work->nrepeats > 0)
4291 {
4292 --work->nrepeats;
4293
4294 if (work->previous_argument == 0)
4295 return 0;
4296
4297 /* We want to reissue the previous type in this argument list. */
4298 string_appends (result, work->previous_argument);
4299 return 1;
4300 }
4301
4302 if (**mangled == 'n')
4303 {
4304 /* A squangling-style repeat. */
4305 (*mangled)++;
4306 work->nrepeats = consume_count(mangled);
4307
4308 if (work->nrepeats <= 0)
4309 /* This was not a repeat count after all. */
4310 return 0;
4311
4312 if (work->nrepeats > 9)
4313 {
4314 if (**mangled != '_')
4315 /* The repeat count should be followed by an '_' in this
4316 case. */
4317 return 0;
4318 else
4319 (*mangled)++;
4320 }
4321
4322 /* Now, the repeat is all set up. */
4323 return do_arg (work, mangled, result);
4324 }
4325
4326 /* Save the result in WORK->previous_argument so that we can find it
4327 if it's repeated. Note that saving START is not good enough: we
4328 do not want to add additional types to the back-referenceable
4329 type vector when processing a repeated type. */
4330 if (work->previous_argument)
4331 string_delete (work->previous_argument);
4332 else
4333 work->previous_argument = XNEW (string);
4334
4335 if (!do_type (work, mangled, work->previous_argument))
4336 return 0;
4337
4338 string_appends (result, work->previous_argument);
4339
4340 remember_type (work, start, *mangled - start);
4341 return 1;
4342 }
4343
4344 static void
4345 push_processed_type (struct work_stuff *work, int typevec_index)
4346 {
4347 if (work->nproctypes >= work->proctypevec_size)
4348 {
4349 if (!work->proctypevec_size)
4350 {
4351 work->proctypevec_size = 4;
4352 work->proctypevec = XNEWVEC (int, work->proctypevec_size);
4353 }
4354 else
4355 {
4356 if (work->proctypevec_size < 16)
4357 /* Double when small. */
4358 work->proctypevec_size *= 2;
4359 else
4360 {
4361 /* Grow slower when large. */
4362 if (work->proctypevec_size > (INT_MAX / 3) * 2)
4363 xmalloc_failed (INT_MAX);
4364 work->proctypevec_size = (work->proctypevec_size * 3 / 2);
4365 }
4366 work->proctypevec
4367 = XRESIZEVEC (int, work->proctypevec, work->proctypevec_size);
4368 }
4369 }
4370 work->proctypevec [work->nproctypes++] = typevec_index;
4371 }
4372
4373 static void
4374 pop_processed_type (struct work_stuff *work)
4375 {
4376 work->nproctypes--;
4377 }
4378
4379 static void
4380 remember_type (struct work_stuff *work, const char *start, int len)
4381 {
4382 char *tem;
4383
4384 if (work->forgetting_types)
4385 return;
4386
4387 if (work -> ntypes >= work -> typevec_size)
4388 {
4389 if (work -> typevec_size == 0)
4390 {
4391 work -> typevec_size = 3;
4392 work -> typevec = XNEWVEC (char *, work->typevec_size);
4393 }
4394 else
4395 {
4396 if (work -> typevec_size > INT_MAX / 2)
4397 xmalloc_failed (INT_MAX);
4398 work -> typevec_size *= 2;
4399 work -> typevec
4400 = XRESIZEVEC (char *, work->typevec, work->typevec_size);
4401 }
4402 }
4403 tem = XNEWVEC (char, len + 1);
4404 memcpy (tem, start, len);
4405 tem[len] = '\0';
4406 work -> typevec[work -> ntypes++] = tem;
4407 }
4408
4409
4410 /* Remember a K type class qualifier. */
4411 static void
4412 remember_Ktype (struct work_stuff *work, const char *start, int len)
4413 {
4414 char *tem;
4415
4416 if (work -> numk >= work -> ksize)
4417 {
4418 if (work -> ksize == 0)
4419 {
4420 work -> ksize = 5;
4421 work -> ktypevec = XNEWVEC (char *, work->ksize);
4422 }
4423 else
4424 {
4425 if (work -> ksize > INT_MAX / 2)
4426 xmalloc_failed (INT_MAX);
4427 work -> ksize *= 2;
4428 work -> ktypevec
4429 = XRESIZEVEC (char *, work->ktypevec, work->ksize);
4430 }
4431 }
4432 tem = XNEWVEC (char, len + 1);
4433 memcpy (tem, start, len);
4434 tem[len] = '\0';
4435 work -> ktypevec[work -> numk++] = tem;
4436 }
4437
4438 /* Register a B code, and get an index for it. B codes are registered
4439 as they are seen, rather than as they are completed, so map<temp<char> >
4440 registers map<temp<char> > as B0, and temp<char> as B1 */
4441
4442 static int
4443 register_Btype (struct work_stuff *work)
4444 {
4445 int ret;
4446
4447 if (work -> numb >= work -> bsize)
4448 {
4449 if (work -> bsize == 0)
4450 {
4451 work -> bsize = 5;
4452 work -> btypevec = XNEWVEC (char *, work->bsize);
4453 }
4454 else
4455 {
4456 if (work -> bsize > INT_MAX / 2)
4457 xmalloc_failed (INT_MAX);
4458 work -> bsize *= 2;
4459 work -> btypevec
4460 = XRESIZEVEC (char *, work->btypevec, work->bsize);
4461 }
4462 }
4463 ret = work -> numb++;
4464 work -> btypevec[ret] = NULL;
4465 return(ret);
4466 }
4467
4468 /* Store a value into a previously registered B code type. */
4469
4470 static void
4471 remember_Btype (struct work_stuff *work, const char *start,
4472 int len, int index)
4473 {
4474 char *tem;
4475
4476 tem = XNEWVEC (char, len + 1);
4477 memcpy (tem, start, len);
4478 tem[len] = '\0';
4479 work -> btypevec[index] = tem;
4480 }
4481
4482 /* Lose all the info related to B and K type codes. */
4483 static void
4484 forget_B_and_K_types (struct work_stuff *work)
4485 {
4486 int i;
4487
4488 while (work -> numk > 0)
4489 {
4490 i = --(work -> numk);
4491 if (work -> ktypevec[i] != NULL)
4492 {
4493 free (work -> ktypevec[i]);
4494 work -> ktypevec[i] = NULL;
4495 }
4496 }
4497
4498 while (work -> numb > 0)
4499 {
4500 i = --(work -> numb);
4501 if (work -> btypevec[i] != NULL)
4502 {
4503 free (work -> btypevec[i]);
4504 work -> btypevec[i] = NULL;
4505 }
4506 }
4507 }
4508 /* Forget the remembered types, but not the type vector itself. */
4509
4510 static void
4511 forget_types (struct work_stuff *work)
4512 {
4513 int i;
4514
4515 while (work -> ntypes > 0)
4516 {
4517 i = --(work -> ntypes);
4518 if (work -> typevec[i] != NULL)
4519 {
4520 free (work -> typevec[i]);
4521 work -> typevec[i] = NULL;
4522 }
4523 }
4524 }
4525
4526 /* Process the argument list part of the signature, after any class spec
4527 has been consumed, as well as the first 'F' character (if any). For
4528 example:
4529
4530 "__als__3fooRT0" => process "RT0"
4531 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4532
4533 DECLP must be already initialised, usually non-empty. It won't be freed
4534 on failure.
4535
4536 Note that g++ differs significantly from ARM and lucid style mangling
4537 with regards to references to previously seen types. For example, given
4538 the source fragment:
4539
4540 class foo {
4541 public:
4542 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4543 };
4544
4545 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4546 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4547
4548 g++ produces the names:
4549
4550 __3fooiRT0iT2iT2
4551 foo__FiR3fooiT1iT1
4552
4553 while lcc (and presumably other ARM style compilers as well) produces:
4554
4555 foo__FiR3fooT1T2T1T2
4556 __ct__3fooFiR3fooT1T2T1T2
4557
4558 Note that g++ bases its type numbers starting at zero and counts all
4559 previously seen types, while lucid/ARM bases its type numbers starting
4560 at one and only considers types after it has seen the 'F' character
4561 indicating the start of the function args. For lucid/ARM style, we
4562 account for this difference by discarding any previously seen types when
4563 we see the 'F' character, and subtracting one from the type number
4564 reference.
4565
4566 */
4567
4568 static int
4569 demangle_args (struct work_stuff *work, const char **mangled,
4570 string *declp)
4571 {
4572 string arg;
4573 int need_comma = 0;
4574 int r;
4575 int t;
4576 const char *tem;
4577 char temptype;
4578
4579 if (PRINT_ARG_TYPES)
4580 {
4581 string_append (declp, "(");
4582 if (**mangled == '\0')
4583 {
4584 string_append (declp, "void");
4585 }
4586 }
4587
4588 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4589 || work->nrepeats > 0)
4590 {
4591 if ((**mangled == 'N') || (**mangled == 'T'))
4592 {
4593 temptype = *(*mangled)++;
4594
4595 if (temptype == 'N')
4596 {
4597 if (!get_count (mangled, &r))
4598 {
4599 return (0);
4600 }
4601 }
4602 else
4603 {
4604 r = 1;
4605 }
4606 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4607 {
4608 /* If we have 10 or more types we might have more than a 1 digit
4609 index so we'll have to consume the whole count here. This
4610 will lose if the next thing is a type name preceded by a
4611 count but it's impossible to demangle that case properly
4612 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4613 Pc, ...)" or "(..., type12, char *, ...)" */
4614 if ((t = consume_count(mangled)) <= 0)
4615 {
4616 return (0);
4617 }
4618 }
4619 else
4620 {
4621 if (!get_count (mangled, &t))
4622 {
4623 return (0);
4624 }
4625 }
4626 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4627 {
4628 t--;
4629 }
4630 /* Validate the type index. Protect against illegal indices from
4631 malformed type strings. */
4632 if ((t < 0) || (t >= work -> ntypes))
4633 {
4634 return (0);
4635 }
4636 while (work->nrepeats > 0 || --r >= 0)
4637 {
4638 tem = work -> typevec[t];
4639 if (need_comma && PRINT_ARG_TYPES)
4640 {
4641 string_append (declp, ", ");
4642 }
4643 push_processed_type (work, t);
4644 if (!do_arg (work, &tem, &arg))
4645 {
4646 pop_processed_type (work);
4647 return (0);
4648 }
4649 pop_processed_type (work);
4650 if (PRINT_ARG_TYPES)
4651 {
4652 string_appends (declp, &arg);
4653 }
4654 string_delete (&arg);
4655 need_comma = 1;
4656 }
4657 }
4658 else
4659 {
4660 if (need_comma && PRINT_ARG_TYPES)
4661 string_append (declp, ", ");
4662 if (!do_arg (work, mangled, &arg))
4663 return (0);
4664 if (PRINT_ARG_TYPES)
4665 string_appends (declp, &arg);
4666 string_delete (&arg);
4667 need_comma = 1;
4668 }
4669 }
4670
4671 if (**mangled == 'e')
4672 {
4673 (*mangled)++;
4674 if (PRINT_ARG_TYPES)
4675 {
4676 if (need_comma)
4677 {
4678 string_append (declp, ",");
4679 }
4680 string_append (declp, "...");
4681 }
4682 }
4683
4684 if (PRINT_ARG_TYPES)
4685 {
4686 string_append (declp, ")");
4687 }
4688 return (1);
4689 }
4690
4691 /* Like demangle_args, but for demangling the argument lists of function
4692 and method pointers or references, not top-level declarations. */
4693
4694 static int
4695 demangle_nested_args (struct work_stuff *work, const char **mangled,
4696 string *declp)
4697 {
4698 string* saved_previous_argument;
4699 int result;
4700 int saved_nrepeats;
4701
4702 /* The G++ name-mangling algorithm does not remember types on nested
4703 argument lists, unless -fsquangling is used, and in that case the
4704 type vector updated by remember_type is not used. So, we turn
4705 off remembering of types here. */
4706 ++work->forgetting_types;
4707
4708 /* For the repeat codes used with -fsquangling, we must keep track of
4709 the last argument. */
4710 saved_previous_argument = work->previous_argument;
4711 saved_nrepeats = work->nrepeats;
4712 work->previous_argument = 0;
4713 work->nrepeats = 0;
4714
4715 /* Actually demangle the arguments. */
4716 result = demangle_args (work, mangled, declp);
4717
4718 /* Restore the previous_argument field. */
4719 if (work->previous_argument)
4720 {
4721 string_delete (work->previous_argument);
4722 free ((char *) work->previous_argument);
4723 }
4724 work->previous_argument = saved_previous_argument;
4725 --work->forgetting_types;
4726 work->nrepeats = saved_nrepeats;
4727
4728 return result;
4729 }
4730
4731 /* Returns 1 if a valid function name was found or 0 otherwise. */
4732
4733 static int
4734 demangle_function_name (struct work_stuff *work, const char **mangled,
4735 string *declp, const char *scan)
4736 {
4737 size_t i;
4738 string type;
4739 const char *tem;
4740
4741 string_appendn (declp, (*mangled), scan - (*mangled));
4742 string_need (declp, 1);
4743 *(declp -> p) = '\0';
4744
4745 /* Consume the function name, including the "__" separating the name
4746 from the signature. We are guaranteed that SCAN points to the
4747 separator. */
4748
4749 (*mangled) = scan + 2;
4750 /* We may be looking at an instantiation of a template function:
4751 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4752 following _F marks the start of the function arguments. Handle
4753 the template arguments first. */
4754
4755 if (HP_DEMANGLING && (**mangled == 'X'))
4756 {
4757 demangle_arm_hp_template (work, mangled, 0, declp);
4758 /* This leaves MANGLED pointing to the 'F' marking func args */
4759 }
4760
4761 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4762 {
4763
4764 /* See if we have an ARM style constructor or destructor operator.
4765 If so, then just record it, clear the decl, and return.
4766 We can't build the actual constructor/destructor decl until later,
4767 when we recover the class name from the signature. */
4768
4769 if (strcmp (declp -> b, "__ct") == 0)
4770 {
4771 work -> constructor += 1;
4772 string_clear (declp);
4773 return 1;
4774 }
4775 else if (strcmp (declp -> b, "__dt") == 0)
4776 {
4777 work -> destructor += 1;
4778 string_clear (declp);
4779 return 1;
4780 }
4781 }
4782
4783 if (declp->p - declp->b >= 3
4784 && declp->b[0] == 'o'
4785 && declp->b[1] == 'p'
4786 && strchr (cplus_markers, declp->b[2]) != NULL)
4787 {
4788 /* see if it's an assignment expression */
4789 if (declp->p - declp->b >= 10 /* op$assign_ */
4790 && memcmp (declp->b + 3, "assign_", 7) == 0)
4791 {
4792 for (i = 0; i < ARRAY_SIZE (optable); i++)
4793 {
4794 int len = declp->p - declp->b - 10;
4795 if ((int) strlen (optable[i].in) == len
4796 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4797 {
4798 string_clear (declp);
4799 string_append (declp, "operator");
4800 string_append (declp, optable[i].out);
4801 string_append (declp, "=");
4802 break;
4803 }
4804 }
4805 }
4806 else
4807 {
4808 for (i = 0; i < ARRAY_SIZE (optable); i++)
4809 {
4810 int len = declp->p - declp->b - 3;
4811 if ((int) strlen (optable[i].in) == len
4812 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4813 {
4814 string_clear (declp);
4815 string_append (declp, "operator");
4816 string_append (declp, optable[i].out);
4817 break;
4818 }
4819 }
4820 }
4821 }
4822 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4823 && strchr (cplus_markers, declp->b[4]) != NULL)
4824 {
4825 /* type conversion operator */
4826 tem = declp->b + 5;
4827 if (do_type (work, &tem, &type))
4828 {
4829 string_clear (declp);
4830 string_append (declp, "operator ");
4831 string_appends (declp, &type);
4832 string_delete (&type);
4833 }
4834 }
4835 else if (declp->b[0] == '_' && declp->b[1] == '_'
4836 && declp->b[2] == 'o' && declp->b[3] == 'p')
4837 {
4838 /* ANSI. */
4839 /* type conversion operator. */
4840 tem = declp->b + 4;
4841 if (do_type (work, &tem, &type))
4842 {
4843 string_clear (declp);
4844 string_append (declp, "operator ");
4845 string_appends (declp, &type);
4846 string_delete (&type);
4847 }
4848 }
4849 else if (declp->b[0] == '_' && declp->b[1] == '_'
4850 && ISLOWER((unsigned char)declp->b[2])
4851 && ISLOWER((unsigned char)declp->b[3]))
4852 {
4853 if (declp->b[4] == '\0')
4854 {
4855 /* Operator. */
4856 for (i = 0; i < ARRAY_SIZE (optable); i++)
4857 {
4858 if (strlen (optable[i].in) == 2
4859 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4860 {
4861 string_clear (declp);
4862 string_append (declp, "operator");
4863 string_append (declp, optable[i].out);
4864 break;
4865 }
4866 }
4867 }
4868 else
4869 {
4870 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4871 {
4872 /* Assignment. */
4873 for (i = 0; i < ARRAY_SIZE (optable); i++)
4874 {
4875 if (strlen (optable[i].in) == 3
4876 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4877 {
4878 string_clear (declp);
4879 string_append (declp, "operator");
4880 string_append (declp, optable[i].out);
4881 break;
4882 }
4883 }
4884 }
4885 }
4886 }
4887
4888 /* If a function name was obtained but it's not valid, we were not
4889 successful. */
4890 if (LEN_STRING (declp) == 1 && declp->b[0] == '.')
4891 return 0;
4892 else
4893 return 1;
4894 }
4895
4896 /* a mini string-handling package */
4897
4898 static void
4899 string_need (string *s, int n)
4900 {
4901 int tem;
4902
4903 if (s->b == NULL)
4904 {
4905 if (n < 32)
4906 {
4907 n = 32;
4908 }
4909 s->p = s->b = XNEWVEC (char, n);
4910 s->e = s->b + n;
4911 }
4912 else if (s->e - s->p < n)
4913 {
4914 tem = s->p - s->b;
4915 if (n > INT_MAX / 2 - tem)
4916 xmalloc_failed (INT_MAX);
4917 n += tem;
4918 n *= 2;
4919 s->b = XRESIZEVEC (char, s->b, n);
4920 s->p = s->b + tem;
4921 s->e = s->b + n;
4922 }
4923 }
4924
4925 static void
4926 string_delete (string *s)
4927 {
4928 if (s->b != NULL)
4929 {
4930 free (s->b);
4931 s->b = s->e = s->p = NULL;
4932 }
4933 }
4934
4935 static void
4936 string_init (string *s)
4937 {
4938 s->b = s->p = s->e = NULL;
4939 }
4940
4941 static void
4942 string_clear (string *s)
4943 {
4944 s->p = s->b;
4945 }
4946
4947 #if 0
4948
4949 static int
4950 string_empty (string *s)
4951 {
4952 return (s->b == s->p);
4953 }
4954
4955 #endif
4956
4957 static void
4958 string_append (string *p, const char *s)
4959 {
4960 int n;
4961 if (s == NULL || *s == '\0')
4962 return;
4963 n = strlen (s);
4964 string_need (p, n);
4965 memcpy (p->p, s, n);
4966 p->p += n;
4967 }
4968
4969 static void
4970 string_appends (string *p, string *s)
4971 {
4972 int n;
4973
4974 if (s->b != s->p)
4975 {
4976 n = s->p - s->b;
4977 string_need (p, n);
4978 memcpy (p->p, s->b, n);
4979 p->p += n;
4980 }
4981 }
4982
4983 static void
4984 string_appendn (string *p, const char *s, int n)
4985 {
4986 if (n != 0)
4987 {
4988 string_need (p, n);
4989 memcpy (p->p, s, n);
4990 p->p += n;
4991 }
4992 }
4993
4994 static void
4995 string_prepend (string *p, const char *s)
4996 {
4997 if (s != NULL && *s != '\0')
4998 {
4999 string_prependn (p, s, strlen (s));
5000 }
5001 }
5002
5003 static void
5004 string_prepends (string *p, string *s)
5005 {
5006 if (s->b != s->p)
5007 {
5008 string_prependn (p, s->b, s->p - s->b);
5009 }
5010 }
5011
5012 static void
5013 string_prependn (string *p, const char *s, int n)
5014 {
5015 char *q;
5016
5017 if (n != 0)
5018 {
5019 string_need (p, n);
5020 for (q = p->p - 1; q >= p->b; q--)
5021 {
5022 q[n] = q[0];
5023 }
5024 memcpy (p->b, s, n);
5025 p->p += n;
5026 }
5027 }
5028
5029 static void
5030 string_append_template_idx (string *s, int idx)
5031 {
5032 char buf[INTBUF_SIZE + 1 /* 'T' */];
5033 sprintf(buf, "T%d", idx);
5034 string_append (s, buf);
5035 }