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