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