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