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