]> git.ipfire.org Git - thirdparty/gcc.git/blob - libiberty/cplus-dem.c
Fix from Marcus Daniels:
[thirdparty/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 if (**mangled == 'Q')
1509 success = demangle_qualified (work, mangled, s,
1510 /*isfuncname=*/0,
1511 /*append=*/1);
1512 else
1513 {
1514 int symbol_len = consume_count (mangled);
1515 if (symbol_len == -1)
1516 return -1;
1517 if (symbol_len == 0)
1518 string_appendn (s, "0", 1);
1519 else
1520 {
1521 char *p = xmalloc (symbol_len + 1), *q;
1522 strncpy (p, *mangled, symbol_len);
1523 p [symbol_len] = '\0';
1524 /* We use cplus_demangle here, rather than
1525 internal_cplus_demangle, because the name of the entity
1526 mangled here does not make use of any of the squangling
1527 or type-code information we have built up thus far; it is
1528 mangled independently. */
1529 q = cplus_demangle (p, work->options);
1530 if (tk == tk_pointer)
1531 string_appendn (s, "&", 1);
1532 /* FIXME: Pointer-to-member constants should get a
1533 qualifying class name here. */
1534 if (q)
1535 {
1536 string_append (s, q);
1537 free (q);
1538 }
1539 else
1540 string_append (s, p);
1541 free (p);
1542 }
1543 *mangled += symbol_len;
1544 }
1545 }
1546
1547 return success;
1548 }
1549
1550 /* Demangle the template name in MANGLED. The full name of the
1551 template (e.g., S<int>) is placed in TNAME. The name without the
1552 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1553 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1554 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1555 the tmeplate is remembered in the list of back-referenceable
1556 types. */
1557
1558 static int
1559 demangle_template (work, mangled, tname, trawname, is_type, remember)
1560 struct work_stuff *work;
1561 const char **mangled;
1562 string *tname;
1563 string *trawname;
1564 int is_type;
1565 int remember;
1566 {
1567 int i;
1568 int r;
1569 int need_comma = 0;
1570 int success = 0;
1571 const char *start;
1572 int is_java_array = 0;
1573 string temp;
1574 int bindex = 0;
1575
1576 (*mangled)++;
1577 if (is_type)
1578 {
1579 if (remember)
1580 bindex = register_Btype (work);
1581 start = *mangled;
1582 /* get template name */
1583 if (**mangled == 'z')
1584 {
1585 int idx;
1586 (*mangled)++;
1587 (*mangled)++;
1588
1589 idx = consume_count_with_underscores (mangled);
1590 if (idx == -1
1591 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1592 || consume_count_with_underscores (mangled) == -1)
1593 return (0);
1594
1595 if (work->tmpl_argvec)
1596 {
1597 string_append (tname, work->tmpl_argvec[idx]);
1598 if (trawname)
1599 string_append (trawname, work->tmpl_argvec[idx]);
1600 }
1601 else
1602 {
1603 char buf[10];
1604 sprintf(buf, "T%d", idx);
1605 string_append (tname, buf);
1606 if (trawname)
1607 string_append (trawname, buf);
1608 }
1609 }
1610 else
1611 {
1612 if ((r = consume_count (mangled)) <= 0
1613 || (int) strlen (*mangled) < r)
1614 {
1615 return (0);
1616 }
1617 is_java_array = (work -> options & DMGL_JAVA)
1618 && strncmp (*mangled, "JArray1Z", 8) == 0;
1619 if (! is_java_array)
1620 {
1621 string_appendn (tname, *mangled, r);
1622 }
1623 if (trawname)
1624 string_appendn (trawname, *mangled, r);
1625 *mangled += r;
1626 }
1627 }
1628 if (!is_java_array)
1629 string_append (tname, "<");
1630 /* get size of template parameter list */
1631 if (!get_count (mangled, &r))
1632 {
1633 return (0);
1634 }
1635 if (!is_type)
1636 {
1637 /* Create an array for saving the template argument values. */
1638 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1639 work->ntmpl_args = r;
1640 for (i = 0; i < r; i++)
1641 work->tmpl_argvec[i] = 0;
1642 }
1643 for (i = 0; i < r; i++)
1644 {
1645 if (need_comma)
1646 {
1647 string_append (tname, ", ");
1648 }
1649 /* Z for type parameters */
1650 if (**mangled == 'Z')
1651 {
1652 (*mangled)++;
1653 /* temp is initialized in do_type */
1654 success = do_type (work, mangled, &temp);
1655 if (success)
1656 {
1657 string_appends (tname, &temp);
1658
1659 if (!is_type)
1660 {
1661 /* Save the template argument. */
1662 int len = temp.p - temp.b;
1663 work->tmpl_argvec[i] = xmalloc (len + 1);
1664 memcpy (work->tmpl_argvec[i], temp.b, len);
1665 work->tmpl_argvec[i][len] = '\0';
1666 }
1667 }
1668 string_delete(&temp);
1669 if (!success)
1670 {
1671 break;
1672 }
1673 }
1674 /* z for template parameters */
1675 else if (**mangled == 'z')
1676 {
1677 int r2;
1678 (*mangled)++;
1679 success = demangle_template_template_parm (work, mangled, tname);
1680
1681 if (success
1682 && (r2 = consume_count (mangled)) > 0
1683 && (int) strlen (*mangled) >= r2)
1684 {
1685 string_append (tname, " ");
1686 string_appendn (tname, *mangled, r2);
1687 if (!is_type)
1688 {
1689 /* Save the template argument. */
1690 int len = r2;
1691 work->tmpl_argvec[i] = xmalloc (len + 1);
1692 memcpy (work->tmpl_argvec[i], *mangled, len);
1693 work->tmpl_argvec[i][len] = '\0';
1694 }
1695 *mangled += r2;
1696 }
1697 if (!success)
1698 {
1699 break;
1700 }
1701 }
1702 else
1703 {
1704 string param;
1705 string* s;
1706
1707 /* otherwise, value parameter */
1708
1709 /* temp is initialized in do_type */
1710 success = do_type (work, mangled, &temp);
1711 string_delete(&temp);
1712 if (!success)
1713 break;
1714
1715 if (!is_type)
1716 {
1717 s = &param;
1718 string_init (s);
1719 }
1720 else
1721 s = tname;
1722
1723 success = demangle_template_value_parm (work, mangled, s,
1724 (type_kind_t) success);
1725
1726 if (!success)
1727 {
1728 if (!is_type)
1729 string_delete (s);
1730 success = 0;
1731 break;
1732 }
1733
1734 if (!is_type)
1735 {
1736 int len = s->p - s->b;
1737 work->tmpl_argvec[i] = xmalloc (len + 1);
1738 memcpy (work->tmpl_argvec[i], s->b, len);
1739 work->tmpl_argvec[i][len] = '\0';
1740
1741 string_appends (tname, s);
1742 string_delete (s);
1743 }
1744 }
1745 need_comma = 1;
1746 }
1747 if (is_java_array)
1748 {
1749 string_append (tname, "[]");
1750 }
1751 else
1752 {
1753 if (tname->p[-1] == '>')
1754 string_append (tname, " ");
1755 string_append (tname, ">");
1756 }
1757
1758 if (is_type && remember)
1759 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1760
1761 /*
1762 if (work -> static_type)
1763 {
1764 string_append (declp, *mangled + 1);
1765 *mangled += strlen (*mangled);
1766 success = 1;
1767 }
1768 else
1769 {
1770 success = demangle_args (work, mangled, declp);
1771 }
1772 }
1773 */
1774 return (success);
1775 }
1776
1777 static int
1778 arm_pt (work, mangled, n, anchor, args)
1779 struct work_stuff *work;
1780 const char *mangled;
1781 int n;
1782 const char **anchor, **args;
1783 {
1784 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1785 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1786 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1787 {
1788 int len;
1789 *args = *anchor + 6;
1790 len = consume_count (args);
1791 if (len == -1)
1792 return 0;
1793 if (*args + len == mangled + n && **args == '_')
1794 {
1795 ++*args;
1796 return 1;
1797 }
1798 }
1799 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1800 {
1801 if ((*anchor = mystrstr (mangled, "__tm__"))
1802 || (*anchor = mystrstr (mangled, "__ps__"))
1803 || (*anchor = mystrstr (mangled, "__pt__")))
1804 {
1805 int len;
1806 *args = *anchor + 6;
1807 len = consume_count (args);
1808 if (len == -1)
1809 return 0;
1810 if (*args + len == mangled + n && **args == '_')
1811 {
1812 ++*args;
1813 return 1;
1814 }
1815 }
1816 else if ((*anchor = mystrstr (mangled, "__S")))
1817 {
1818 int len;
1819 *args = *anchor + 3;
1820 len = consume_count (args);
1821 if (len == -1)
1822 return 0;
1823 if (*args + len == mangled + n && **args == '_')
1824 {
1825 ++*args;
1826 return 1;
1827 }
1828 }
1829 }
1830
1831 return 0;
1832 }
1833
1834 static void
1835 demangle_arm_hp_template (work, mangled, n, declp)
1836 struct work_stuff *work;
1837 const char **mangled;
1838 int n;
1839 string *declp;
1840 {
1841 const char *p;
1842 const char *args;
1843 const char *e = *mangled + n;
1844 string arg;
1845
1846 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1847 template args */
1848 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1849 {
1850 char *start_spec_args = NULL;
1851
1852 /* First check for and omit template specialization pseudo-arguments,
1853 such as in "Spec<#1,#1.*>" */
1854 start_spec_args = strchr (*mangled, '<');
1855 if (start_spec_args && (start_spec_args - *mangled < n))
1856 string_appendn (declp, *mangled, start_spec_args - *mangled);
1857 else
1858 string_appendn (declp, *mangled, n);
1859 (*mangled) += n + 1;
1860 string_init (&arg);
1861 if (work->temp_start == -1) /* non-recursive call */
1862 work->temp_start = declp->p - declp->b;
1863 string_append (declp, "<");
1864 while (1)
1865 {
1866 string_clear (&arg);
1867 switch (**mangled)
1868 {
1869 case 'T':
1870 /* 'T' signals a type parameter */
1871 (*mangled)++;
1872 if (!do_type (work, mangled, &arg))
1873 goto hpacc_template_args_done;
1874 break;
1875
1876 case 'U':
1877 case 'S':
1878 /* 'U' or 'S' signals an integral value */
1879 if (!do_hpacc_template_const_value (work, mangled, &arg))
1880 goto hpacc_template_args_done;
1881 break;
1882
1883 case 'A':
1884 /* 'A' signals a named constant expression (literal) */
1885 if (!do_hpacc_template_literal (work, mangled, &arg))
1886 goto hpacc_template_args_done;
1887 break;
1888
1889 default:
1890 /* Today, 1997-09-03, we have only the above types
1891 of template parameters */
1892 /* FIXME: maybe this should fail and return null */
1893 goto hpacc_template_args_done;
1894 }
1895 string_appends (declp, &arg);
1896 /* Check if we're at the end of template args.
1897 0 if at end of static member of template class,
1898 _ if done with template args for a function */
1899 if ((**mangled == '\000') || (**mangled == '_'))
1900 break;
1901 else
1902 string_append (declp, ",");
1903 }
1904 hpacc_template_args_done:
1905 string_append (declp, ">");
1906 string_delete (&arg);
1907 if (**mangled == '_')
1908 (*mangled)++;
1909 return;
1910 }
1911 /* ARM template? (Also handles HP cfront extensions) */
1912 else if (arm_pt (work, *mangled, n, &p, &args))
1913 {
1914 string type_str;
1915
1916 string_init (&arg);
1917 string_appendn (declp, *mangled, p - *mangled);
1918 if (work->temp_start == -1) /* non-recursive call */
1919 work->temp_start = declp->p - declp->b;
1920 string_append (declp, "<");
1921 /* should do error checking here */
1922 while (args < e) {
1923 string_clear (&arg);
1924
1925 /* Check for type or literal here */
1926 switch (*args)
1927 {
1928 /* HP cfront extensions to ARM for template args */
1929 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1930 /* FIXME: We handle only numeric literals for HP cfront */
1931 case 'X':
1932 /* A typed constant value follows */
1933 args++;
1934 if (!do_type (work, &args, &type_str))
1935 goto cfront_template_args_done;
1936 string_append (&arg, "(");
1937 string_appends (&arg, &type_str);
1938 string_append (&arg, ")");
1939 if (*args != 'L')
1940 goto cfront_template_args_done;
1941 args++;
1942 /* Now snarf a literal value following 'L' */
1943 if (!snarf_numeric_literal (&args, &arg))
1944 goto cfront_template_args_done;
1945 break;
1946
1947 case 'L':
1948 /* Snarf a literal following 'L' */
1949 args++;
1950 if (!snarf_numeric_literal (&args, &arg))
1951 goto cfront_template_args_done;
1952 break;
1953 default:
1954 /* Not handling other HP cfront stuff */
1955 if (!do_type (work, &args, &arg))
1956 goto cfront_template_args_done;
1957 }
1958 string_appends (declp, &arg);
1959 string_append (declp, ",");
1960 }
1961 cfront_template_args_done:
1962 string_delete (&arg);
1963 if (args >= e)
1964 --declp->p; /* remove extra comma */
1965 string_append (declp, ">");
1966 }
1967 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1968 && (*mangled)[9] == 'N'
1969 && (*mangled)[8] == (*mangled)[10]
1970 && strchr (cplus_markers, (*mangled)[8]))
1971 {
1972 /* A member of the anonymous namespace. */
1973 string_append (declp, "{anonymous}");
1974 }
1975 else
1976 {
1977 if (work->temp_start == -1) /* non-recursive call only */
1978 work->temp_start = 0; /* disable in recursive calls */
1979 string_appendn (declp, *mangled, n);
1980 }
1981 *mangled += n;
1982 }
1983
1984 /* Extract a class name, possibly a template with arguments, from the
1985 mangled string; qualifiers, local class indicators, etc. have
1986 already been dealt with */
1987
1988 static int
1989 demangle_class_name (work, mangled, declp)
1990 struct work_stuff *work;
1991 const char **mangled;
1992 string *declp;
1993 {
1994 int n;
1995 int success = 0;
1996
1997 n = consume_count (mangled);
1998 if (n == -1)
1999 return 0;
2000 if ((int) strlen (*mangled) >= n)
2001 {
2002 demangle_arm_hp_template (work, mangled, n, declp);
2003 success = 1;
2004 }
2005
2006 return (success);
2007 }
2008
2009 /*
2010
2011 LOCAL FUNCTION
2012
2013 demangle_class -- demangle a mangled class sequence
2014
2015 SYNOPSIS
2016
2017 static int
2018 demangle_class (struct work_stuff *work, const char **mangled,
2019 strint *declp)
2020
2021 DESCRIPTION
2022
2023 DECLP points to the buffer into which demangling is being done.
2024
2025 *MANGLED points to the current token to be demangled. On input,
2026 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2027 On exit, it points to the next token after the mangled class on
2028 success, or the first unconsumed token on failure.
2029
2030 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2031 we are demangling a constructor or destructor. In this case
2032 we prepend "class::class" or "class::~class" to DECLP.
2033
2034 Otherwise, we prepend "class::" to the current DECLP.
2035
2036 Reset the constructor/destructor flags once they have been
2037 "consumed". This allows demangle_class to be called later during
2038 the same demangling, to do normal class demangling.
2039
2040 Returns 1 if demangling is successful, 0 otherwise.
2041
2042 */
2043
2044 static int
2045 demangle_class (work, mangled, declp)
2046 struct work_stuff *work;
2047 const char **mangled;
2048 string *declp;
2049 {
2050 int success = 0;
2051 int btype;
2052 string class_name;
2053 char *save_class_name_end = 0;
2054
2055 string_init (&class_name);
2056 btype = register_Btype (work);
2057 if (demangle_class_name (work, mangled, &class_name))
2058 {
2059 save_class_name_end = class_name.p;
2060 if ((work->constructor & 1) || (work->destructor & 1))
2061 {
2062 /* adjust so we don't include template args */
2063 if (work->temp_start && (work->temp_start != -1))
2064 {
2065 class_name.p = class_name.b + work->temp_start;
2066 }
2067 string_prepends (declp, &class_name);
2068 if (work -> destructor & 1)
2069 {
2070 string_prepend (declp, "~");
2071 work -> destructor -= 1;
2072 }
2073 else
2074 {
2075 work -> constructor -= 1;
2076 }
2077 }
2078 class_name.p = save_class_name_end;
2079 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2080 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2081 string_prepend (declp, SCOPE_STRING (work));
2082 string_prepends (declp, &class_name);
2083 success = 1;
2084 }
2085 string_delete (&class_name);
2086 return (success);
2087 }
2088
2089 /*
2090
2091 LOCAL FUNCTION
2092
2093 demangle_prefix -- consume the mangled name prefix and find signature
2094
2095 SYNOPSIS
2096
2097 static int
2098 demangle_prefix (struct work_stuff *work, const char **mangled,
2099 string *declp);
2100
2101 DESCRIPTION
2102
2103 Consume and demangle the prefix of the mangled name.
2104
2105 DECLP points to the string buffer into which demangled output is
2106 placed. On entry, the buffer is empty. On exit it contains
2107 the root function name, the demangled operator name, or in some
2108 special cases either nothing or the completely demangled result.
2109
2110 MANGLED points to the current pointer into the mangled name. As each
2111 token of the mangled name is consumed, it is updated. Upon entry
2112 the current mangled name pointer points to the first character of
2113 the mangled name. Upon exit, it should point to the first character
2114 of the signature if demangling was successful, or to the first
2115 unconsumed character if demangling of the prefix was unsuccessful.
2116
2117 Returns 1 on success, 0 otherwise.
2118 */
2119
2120 static int
2121 demangle_prefix (work, mangled, declp)
2122 struct work_stuff *work;
2123 const char **mangled;
2124 string *declp;
2125 {
2126 int success = 1;
2127 const char *scan;
2128 int i;
2129
2130 if (strlen(*mangled) > 6
2131 && (strncmp(*mangled, "_imp__", 6) == 0
2132 || strncmp(*mangled, "__imp_", 6) == 0))
2133 {
2134 /* it's a symbol imported from a PE dynamic library. Check for both
2135 new style prefix _imp__ and legacy __imp_ used by older versions
2136 of dlltool. */
2137 (*mangled) += 6;
2138 work->dllimported = 1;
2139 }
2140 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2141 {
2142 char *marker = strchr (cplus_markers, (*mangled)[8]);
2143 if (marker != NULL && *marker == (*mangled)[10])
2144 {
2145 if ((*mangled)[9] == 'D')
2146 {
2147 /* it's a GNU global destructor to be executed at program exit */
2148 (*mangled) += 11;
2149 work->destructor = 2;
2150 if (gnu_special (work, mangled, declp))
2151 return success;
2152 }
2153 else if ((*mangled)[9] == 'I')
2154 {
2155 /* it's a GNU global constructor to be executed at program init */
2156 (*mangled) += 11;
2157 work->constructor = 2;
2158 if (gnu_special (work, mangled, declp))
2159 return success;
2160 }
2161 }
2162 }
2163 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2164 {
2165 /* it's a ARM global destructor to be executed at program exit */
2166 (*mangled) += 7;
2167 work->destructor = 2;
2168 }
2169 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2170 {
2171 /* it's a ARM global constructor to be executed at program initial */
2172 (*mangled) += 7;
2173 work->constructor = 2;
2174 }
2175
2176 /* This block of code is a reduction in strength time optimization
2177 of:
2178 scan = mystrstr (*mangled, "__"); */
2179
2180 {
2181 scan = *mangled;
2182
2183 do {
2184 scan = strchr (scan, '_');
2185 } while (scan != NULL && *++scan != '_');
2186
2187 if (scan != NULL) --scan;
2188 }
2189
2190 if (scan != NULL)
2191 {
2192 /* We found a sequence of two or more '_', ensure that we start at
2193 the last pair in the sequence. */
2194 i = strspn (scan, "_");
2195 if (i > 2)
2196 {
2197 scan += (i - 2);
2198 }
2199 }
2200
2201 if (scan == NULL)
2202 {
2203 success = 0;
2204 }
2205 else if (work -> static_type)
2206 {
2207 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2208 {
2209 success = 0;
2210 }
2211 }
2212 else if ((scan == *mangled)
2213 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2214 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2215 {
2216 /* The ARM says nothing about the mangling of local variables.
2217 But cfront mangles local variables by prepending __<nesting_level>
2218 to them. As an extension to ARM demangling we handle this case. */
2219 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2220 && isdigit ((unsigned char)scan[2]))
2221 {
2222 *mangled = scan + 2;
2223 consume_count (mangled);
2224 string_append (declp, *mangled);
2225 *mangled += strlen (*mangled);
2226 success = 1;
2227 }
2228 else
2229 {
2230 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2231 names like __Q2_3foo3bar for nested type names. So don't accept
2232 this style of constructor for cfront demangling. A GNU
2233 style member-template constructor starts with 'H'. */
2234 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2235 work -> constructor += 1;
2236 *mangled = scan + 2;
2237 }
2238 }
2239 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2240 {
2241 /* Cfront-style parameterized type. Handled later as a signature. */
2242 success = 1;
2243
2244 /* ARM template? */
2245 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2246 }
2247 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2248 || (scan[2] == 'p' && scan[3] == 's')
2249 || (scan[2] == 'p' && scan[3] == 't')))
2250 {
2251 /* EDG-style parameterized type. Handled later as a signature. */
2252 success = 1;
2253
2254 /* EDG template? */
2255 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2256 }
2257 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2258 && (scan[2] != 't'))
2259 {
2260 /* Mangled name starts with "__". Skip over any leading '_' characters,
2261 then find the next "__" that separates the prefix from the signature.
2262 */
2263 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2264 || (arm_special (mangled, declp) == 0))
2265 {
2266 while (*scan == '_')
2267 {
2268 scan++;
2269 }
2270 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2271 {
2272 /* No separator (I.E. "__not_mangled"), or empty signature
2273 (I.E. "__not_mangled_either__") */
2274 success = 0;
2275 }
2276 else
2277 {
2278 const char *tmp;
2279
2280 /* Look for the LAST occurrence of __, allowing names to
2281 have the '__' sequence embedded in them. */
2282 if (!(ARM_DEMANGLING || HP_DEMANGLING))
2283 {
2284 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
2285 scan = tmp;
2286 }
2287 if (*(scan + 2) == '\0')
2288 success = 0;
2289 else
2290 demangle_function_name (work, mangled, declp, scan);
2291 }
2292 }
2293 }
2294 else if (*(scan + 2) != '\0')
2295 {
2296 /* Mangled name does not start with "__" but does have one somewhere
2297 in there with non empty stuff after it. Looks like a global
2298 function name. */
2299 demangle_function_name (work, mangled, declp, scan);
2300 }
2301 else
2302 {
2303 /* Doesn't look like a mangled name */
2304 success = 0;
2305 }
2306
2307 if (!success && (work->constructor == 2 || work->destructor == 2))
2308 {
2309 string_append (declp, *mangled);
2310 *mangled += strlen (*mangled);
2311 success = 1;
2312 }
2313 return (success);
2314 }
2315
2316 /*
2317
2318 LOCAL FUNCTION
2319
2320 gnu_special -- special handling of gnu mangled strings
2321
2322 SYNOPSIS
2323
2324 static int
2325 gnu_special (struct work_stuff *work, const char **mangled,
2326 string *declp);
2327
2328
2329 DESCRIPTION
2330
2331 Process some special GNU style mangling forms that don't fit
2332 the normal pattern. For example:
2333
2334 _$_3foo (destructor for class foo)
2335 _vt$foo (foo virtual table)
2336 _vt$foo$bar (foo::bar virtual table)
2337 __vt_foo (foo virtual table, new style with thunks)
2338 _3foo$varname (static data member)
2339 _Q22rs2tu$vw (static data member)
2340 __t6vector1Zii (constructor with template)
2341 __thunk_4__$_7ostream (virtual function thunk)
2342 */
2343
2344 static int
2345 gnu_special (work, mangled, declp)
2346 struct work_stuff *work;
2347 const char **mangled;
2348 string *declp;
2349 {
2350 int n;
2351 int success = 1;
2352 const char *p;
2353
2354 if ((*mangled)[0] == '_'
2355 && strchr (cplus_markers, (*mangled)[1]) != NULL
2356 && (*mangled)[2] == '_')
2357 {
2358 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2359 (*mangled) += 3;
2360 work -> destructor += 1;
2361 }
2362 else if ((*mangled)[0] == '_'
2363 && (((*mangled)[1] == '_'
2364 && (*mangled)[2] == 'v'
2365 && (*mangled)[3] == 't'
2366 && (*mangled)[4] == '_')
2367 || ((*mangled)[1] == 'v'
2368 && (*mangled)[2] == 't'
2369 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2370 {
2371 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2372 and create the decl. Note that we consume the entire mangled
2373 input string, which means that demangle_signature has no work
2374 to do. */
2375 if ((*mangled)[2] == 'v')
2376 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2377 else
2378 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2379 while (**mangled != '\0')
2380 {
2381 switch (**mangled)
2382 {
2383 case 'Q':
2384 case 'K':
2385 success = demangle_qualified (work, mangled, declp, 0, 1);
2386 break;
2387 case 't':
2388 success = demangle_template (work, mangled, declp, 0, 1,
2389 1);
2390 break;
2391 default:
2392 if (isdigit((unsigned char)*mangled[0]))
2393 {
2394 n = consume_count(mangled);
2395 /* We may be seeing a too-large size, or else a
2396 ".<digits>" indicating a static local symbol. In
2397 any case, declare victory and move on; *don't* try
2398 to use n to allocate. */
2399 if (n > (int) strlen (*mangled))
2400 {
2401 success = 1;
2402 break;
2403 }
2404 }
2405 else
2406 {
2407 n = strcspn (*mangled, cplus_markers);
2408 }
2409 string_appendn (declp, *mangled, n);
2410 (*mangled) += n;
2411 }
2412
2413 p = strpbrk (*mangled, cplus_markers);
2414 if (success && ((p == NULL) || (p == *mangled)))
2415 {
2416 if (p != NULL)
2417 {
2418 string_append (declp, SCOPE_STRING (work));
2419 (*mangled)++;
2420 }
2421 }
2422 else
2423 {
2424 success = 0;
2425 break;
2426 }
2427 }
2428 if (success)
2429 string_append (declp, " virtual table");
2430 }
2431 else if ((*mangled)[0] == '_'
2432 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2433 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2434 {
2435 /* static data member, "_3foo$varname" for example */
2436 (*mangled)++;
2437 switch (**mangled)
2438 {
2439 case 'Q':
2440 case 'K':
2441 success = demangle_qualified (work, mangled, declp, 0, 1);
2442 break;
2443 case 't':
2444 success = demangle_template (work, mangled, declp, 0, 1, 1);
2445 break;
2446 default:
2447 n = consume_count (mangled);
2448 if (n < 0 || n > strlen (*mangled))
2449 {
2450 success = 0;
2451 break;
2452 }
2453 string_appendn (declp, *mangled, n);
2454 (*mangled) += n;
2455 }
2456 if (success && (p == *mangled))
2457 {
2458 /* Consumed everything up to the cplus_marker, append the
2459 variable name. */
2460 (*mangled)++;
2461 string_append (declp, SCOPE_STRING (work));
2462 n = strlen (*mangled);
2463 string_appendn (declp, *mangled, n);
2464 (*mangled) += n;
2465 }
2466 else
2467 {
2468 success = 0;
2469 }
2470 }
2471 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2472 {
2473 int delta;
2474
2475 (*mangled) += 8;
2476 delta = consume_count (mangled);
2477 if (delta == -1)
2478 success = 0;
2479 else
2480 {
2481 char *method = internal_cplus_demangle (work, ++*mangled);
2482
2483 if (method)
2484 {
2485 char buf[50];
2486 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2487 string_append (declp, buf);
2488 string_append (declp, method);
2489 free (method);
2490 n = strlen (*mangled);
2491 (*mangled) += n;
2492 }
2493 else
2494 {
2495 success = 0;
2496 }
2497 }
2498 }
2499 else if (strncmp (*mangled, "__t", 3) == 0
2500 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2501 {
2502 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2503 (*mangled) += 4;
2504 switch (**mangled)
2505 {
2506 case 'Q':
2507 case 'K':
2508 success = demangle_qualified (work, mangled, declp, 0, 1);
2509 break;
2510 case 't':
2511 success = demangle_template (work, mangled, declp, 0, 1, 1);
2512 break;
2513 default:
2514 success = demangle_fund_type (work, mangled, declp);
2515 break;
2516 }
2517 if (success && **mangled != '\0')
2518 success = 0;
2519 if (success)
2520 string_append (declp, p);
2521 }
2522 else
2523 {
2524 success = 0;
2525 }
2526 return (success);
2527 }
2528
2529 static void
2530 recursively_demangle(work, mangled, result, namelength)
2531 struct work_stuff *work;
2532 const char **mangled;
2533 string *result;
2534 int namelength;
2535 {
2536 char * recurse = (char *)NULL;
2537 char * recurse_dem = (char *)NULL;
2538
2539 recurse = (char *) xmalloc (namelength + 1);
2540 memcpy (recurse, *mangled, namelength);
2541 recurse[namelength] = '\000';
2542
2543 recurse_dem = cplus_demangle (recurse, work->options);
2544
2545 if (recurse_dem)
2546 {
2547 string_append (result, recurse_dem);
2548 free (recurse_dem);
2549 }
2550 else
2551 {
2552 string_appendn (result, *mangled, namelength);
2553 }
2554 free (recurse);
2555 *mangled += namelength;
2556 }
2557
2558 /*
2559
2560 LOCAL FUNCTION
2561
2562 arm_special -- special handling of ARM/lucid mangled strings
2563
2564 SYNOPSIS
2565
2566 static int
2567 arm_special (const char **mangled,
2568 string *declp);
2569
2570
2571 DESCRIPTION
2572
2573 Process some special ARM style mangling forms that don't fit
2574 the normal pattern. For example:
2575
2576 __vtbl__3foo (foo virtual table)
2577 __vtbl__3foo__3bar (bar::foo virtual table)
2578
2579 */
2580
2581 static int
2582 arm_special (mangled, declp)
2583 const char **mangled;
2584 string *declp;
2585 {
2586 int n;
2587 int success = 1;
2588 const char *scan;
2589
2590 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2591 {
2592 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2593 and create the decl. Note that we consume the entire mangled
2594 input string, which means that demangle_signature has no work
2595 to do. */
2596 scan = *mangled + ARM_VTABLE_STRLEN;
2597 while (*scan != '\0') /* first check it can be demangled */
2598 {
2599 n = consume_count (&scan);
2600 if (n == -1)
2601 {
2602 return (0); /* no good */
2603 }
2604 scan += n;
2605 if (scan[0] == '_' && scan[1] == '_')
2606 {
2607 scan += 2;
2608 }
2609 }
2610 (*mangled) += ARM_VTABLE_STRLEN;
2611 while (**mangled != '\0')
2612 {
2613 n = consume_count (mangled);
2614 if (n == -1
2615 || n > strlen (*mangled))
2616 return 0;
2617 string_prependn (declp, *mangled, n);
2618 (*mangled) += n;
2619 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2620 {
2621 string_prepend (declp, "::");
2622 (*mangled) += 2;
2623 }
2624 }
2625 string_append (declp, " virtual table");
2626 }
2627 else
2628 {
2629 success = 0;
2630 }
2631 return (success);
2632 }
2633
2634 /*
2635
2636 LOCAL FUNCTION
2637
2638 demangle_qualified -- demangle 'Q' qualified name strings
2639
2640 SYNOPSIS
2641
2642 static int
2643 demangle_qualified (struct work_stuff *, const char *mangled,
2644 string *result, int isfuncname, int append);
2645
2646 DESCRIPTION
2647
2648 Demangle a qualified name, such as "Q25Outer5Inner" which is
2649 the mangled form of "Outer::Inner". The demangled output is
2650 prepended or appended to the result string according to the
2651 state of the append flag.
2652
2653 If isfuncname is nonzero, then the qualified name we are building
2654 is going to be used as a member function name, so if it is a
2655 constructor or destructor function, append an appropriate
2656 constructor or destructor name. I.E. for the above example,
2657 the result for use as a constructor is "Outer::Inner::Inner"
2658 and the result for use as a destructor is "Outer::Inner::~Inner".
2659
2660 BUGS
2661
2662 Numeric conversion is ASCII dependent (FIXME).
2663
2664 */
2665
2666 static int
2667 demangle_qualified (work, mangled, result, isfuncname, append)
2668 struct work_stuff *work;
2669 const char **mangled;
2670 string *result;
2671 int isfuncname;
2672 int append;
2673 {
2674 int qualifiers = 0;
2675 int success = 1;
2676 const char *p;
2677 char num[2];
2678 string temp;
2679 string last_name;
2680 int bindex = register_Btype (work);
2681
2682 /* We only make use of ISFUNCNAME if the entity is a constructor or
2683 destructor. */
2684 isfuncname = (isfuncname
2685 && ((work->constructor & 1) || (work->destructor & 1)));
2686
2687 string_init (&temp);
2688 string_init (&last_name);
2689
2690 if ((*mangled)[0] == 'K')
2691 {
2692 /* Squangling qualified name reuse */
2693 int idx;
2694 (*mangled)++;
2695 idx = consume_count_with_underscores (mangled);
2696 if (idx == -1 || idx >= work -> numk)
2697 success = 0;
2698 else
2699 string_append (&temp, work -> ktypevec[idx]);
2700 }
2701 else
2702 switch ((*mangled)[1])
2703 {
2704 case '_':
2705 /* GNU mangled name with more than 9 classes. The count is preceded
2706 by an underscore (to distinguish it from the <= 9 case) and followed
2707 by an underscore. */
2708 p = *mangled + 2;
2709 qualifiers = atoi (p);
2710 if (!isdigit ((unsigned char)*p) || *p == '0')
2711 success = 0;
2712
2713 /* Skip the digits. */
2714 while (isdigit ((unsigned char)*p))
2715 ++p;
2716
2717 if (*p != '_')
2718 success = 0;
2719
2720 *mangled = p + 1;
2721 break;
2722
2723 case '1':
2724 case '2':
2725 case '3':
2726 case '4':
2727 case '5':
2728 case '6':
2729 case '7':
2730 case '8':
2731 case '9':
2732 /* The count is in a single digit. */
2733 num[0] = (*mangled)[1];
2734 num[1] = '\0';
2735 qualifiers = atoi (num);
2736
2737 /* If there is an underscore after the digit, skip it. This is
2738 said to be for ARM-qualified names, but the ARM makes no
2739 mention of such an underscore. Perhaps cfront uses one. */
2740 if ((*mangled)[2] == '_')
2741 {
2742 (*mangled)++;
2743 }
2744 (*mangled) += 2;
2745 break;
2746
2747 case '0':
2748 default:
2749 success = 0;
2750 }
2751
2752 if (!success)
2753 return success;
2754
2755 /* Pick off the names and collect them in the temp buffer in the order
2756 in which they are found, separated by '::'. */
2757
2758 while (qualifiers-- > 0)
2759 {
2760 int remember_K = 1;
2761 string_clear (&last_name);
2762
2763 if (*mangled[0] == '_')
2764 (*mangled)++;
2765
2766 if (*mangled[0] == 't')
2767 {
2768 /* Here we always append to TEMP since we will want to use
2769 the template name without the template parameters as a
2770 constructor or destructor name. The appropriate
2771 (parameter-less) value is returned by demangle_template
2772 in LAST_NAME. We do not remember the template type here,
2773 in order to match the G++ mangling algorithm. */
2774 success = demangle_template(work, mangled, &temp,
2775 &last_name, 1, 0);
2776 if (!success)
2777 break;
2778 }
2779 else if (*mangled[0] == 'K')
2780 {
2781 int idx;
2782 (*mangled)++;
2783 idx = consume_count_with_underscores (mangled);
2784 if (idx == -1 || idx >= work->numk)
2785 success = 0;
2786 else
2787 string_append (&temp, work->ktypevec[idx]);
2788 remember_K = 0;
2789
2790 if (!success) break;
2791 }
2792 else
2793 {
2794 if (EDG_DEMANGLING)
2795 {
2796 int namelength;
2797 /* Now recursively demangle the qualifier
2798 * This is necessary to deal with templates in
2799 * mangling styles like EDG */
2800 namelength = consume_count (mangled);
2801 if (namelength == -1)
2802 {
2803 success = 0;
2804 break;
2805 }
2806 recursively_demangle(work, mangled, &temp, namelength);
2807 }
2808 else
2809 {
2810 success = do_type (work, mangled, &last_name);
2811 if (!success)
2812 break;
2813 string_appends (&temp, &last_name);
2814 }
2815 }
2816
2817 if (remember_K)
2818 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2819
2820 if (qualifiers > 0)
2821 string_append (&temp, SCOPE_STRING (work));
2822 }
2823
2824 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2825
2826 /* If we are using the result as a function name, we need to append
2827 the appropriate '::' separated constructor or destructor name.
2828 We do this here because this is the most convenient place, where
2829 we already have a pointer to the name and the length of the name. */
2830
2831 if (isfuncname)
2832 {
2833 string_append (&temp, SCOPE_STRING (work));
2834 if (work -> destructor & 1)
2835 string_append (&temp, "~");
2836 string_appends (&temp, &last_name);
2837 }
2838
2839 /* Now either prepend the temp buffer to the result, or append it,
2840 depending upon the state of the append flag. */
2841
2842 if (append)
2843 string_appends (result, &temp);
2844 else
2845 {
2846 if (!STRING_EMPTY (result))
2847 string_append (&temp, SCOPE_STRING (work));
2848 string_prepends (result, &temp);
2849 }
2850
2851 string_delete (&last_name);
2852 string_delete (&temp);
2853 return (success);
2854 }
2855
2856 /*
2857
2858 LOCAL FUNCTION
2859
2860 get_count -- convert an ascii count to integer, consuming tokens
2861
2862 SYNOPSIS
2863
2864 static int
2865 get_count (const char **type, int *count)
2866
2867 DESCRIPTION
2868
2869 Assume that *type points at a count in a mangled name; set
2870 *count to its value, and set *type to the next character after
2871 the count. There are some weird rules in effect here.
2872
2873 If *type does not point at a string of digits, return zero.
2874
2875 If *type points at a string of digits followed by an
2876 underscore, set *count to their value as an integer, advance
2877 *type to point *after the underscore, and return 1.
2878
2879 If *type points at a string of digits not followed by an
2880 underscore, consume only the first digit. Set *count to its
2881 value as an integer, leave *type pointing after that digit,
2882 and return 1.
2883
2884 The excuse for this odd behavior: in the ARM and HP demangling
2885 styles, a type can be followed by a repeat count of the form
2886 `Nxy', where:
2887
2888 `x' is a single digit specifying how many additional copies
2889 of the type to append to the argument list, and
2890
2891 `y' is one or more digits, specifying the zero-based index of
2892 the first repeated argument in the list. Yes, as you're
2893 unmangling the name you can figure this out yourself, but
2894 it's there anyway.
2895
2896 So, for example, in `bar__3fooFPiN51', the first argument is a
2897 pointer to an integer (`Pi'), and then the next five arguments
2898 are the same (`N5'), and the first repeat is the function's
2899 second argument (`1').
2900 */
2901
2902 static int
2903 get_count (type, count)
2904 const char **type;
2905 int *count;
2906 {
2907 const char *p;
2908 int n;
2909
2910 if (!isdigit ((unsigned char)**type))
2911 {
2912 return (0);
2913 }
2914 else
2915 {
2916 *count = **type - '0';
2917 (*type)++;
2918 if (isdigit ((unsigned char)**type))
2919 {
2920 p = *type;
2921 n = *count;
2922 do
2923 {
2924 n *= 10;
2925 n += *p - '0';
2926 p++;
2927 }
2928 while (isdigit ((unsigned char)*p));
2929 if (*p == '_')
2930 {
2931 *type = p + 1;
2932 *count = n;
2933 }
2934 }
2935 }
2936 return (1);
2937 }
2938
2939 /* RESULT will be initialised here; it will be freed on failure. The
2940 value returned is really a type_kind_t. */
2941
2942 static int
2943 do_type (work, mangled, result)
2944 struct work_stuff *work;
2945 const char **mangled;
2946 string *result;
2947 {
2948 int n;
2949 int done;
2950 int success;
2951 string decl;
2952 const char *remembered_type;
2953 int type_quals;
2954 string btype;
2955 type_kind_t tk = tk_none;
2956
2957 string_init (&btype);
2958 string_init (&decl);
2959 string_init (result);
2960
2961 done = 0;
2962 success = 1;
2963 while (success && !done)
2964 {
2965 int member;
2966 switch (**mangled)
2967 {
2968
2969 /* A pointer type */
2970 case 'P':
2971 case 'p':
2972 (*mangled)++;
2973 if (! (work -> options & DMGL_JAVA))
2974 string_prepend (&decl, "*");
2975 if (tk == tk_none)
2976 tk = tk_pointer;
2977 break;
2978
2979 /* A reference type */
2980 case 'R':
2981 (*mangled)++;
2982 string_prepend (&decl, "&");
2983 if (tk == tk_none)
2984 tk = tk_reference;
2985 break;
2986
2987 /* An array */
2988 case 'A':
2989 {
2990 ++(*mangled);
2991 if (!STRING_EMPTY (&decl)
2992 && (decl.b[0] == '*' || decl.b[0] == '&'))
2993 {
2994 string_prepend (&decl, "(");
2995 string_append (&decl, ")");
2996 }
2997 string_append (&decl, "[");
2998 if (**mangled != '_')
2999 success = demangle_template_value_parm (work, mangled, &decl,
3000 tk_integral);
3001 if (**mangled == '_')
3002 ++(*mangled);
3003 string_append (&decl, "]");
3004 break;
3005 }
3006
3007 /* A back reference to a previously seen type */
3008 case 'T':
3009 (*mangled)++;
3010 if (!get_count (mangled, &n) || n >= work -> ntypes)
3011 {
3012 success = 0;
3013 }
3014 else
3015 {
3016 remembered_type = work -> typevec[n];
3017 mangled = &remembered_type;
3018 }
3019 break;
3020
3021 /* A function */
3022 case 'F':
3023 (*mangled)++;
3024 if (!STRING_EMPTY (&decl)
3025 && (decl.b[0] == '*' || decl.b[0] == '&'))
3026 {
3027 string_prepend (&decl, "(");
3028 string_append (&decl, ")");
3029 }
3030 /* After picking off the function args, we expect to either find the
3031 function return type (preceded by an '_') or the end of the
3032 string. */
3033 if (!demangle_nested_args (work, mangled, &decl)
3034 || (**mangled != '_' && **mangled != '\0'))
3035 {
3036 success = 0;
3037 break;
3038 }
3039 if (success && (**mangled == '_'))
3040 (*mangled)++;
3041 break;
3042
3043 case 'M':
3044 case 'O':
3045 {
3046 type_quals = TYPE_UNQUALIFIED;
3047
3048 member = **mangled == 'M';
3049 (*mangled)++;
3050
3051 string_append (&decl, ")");
3052 string_prepend (&decl, SCOPE_STRING (work));
3053 if (isdigit ((unsigned char)**mangled))
3054 {
3055 n = consume_count (mangled);
3056 if (n == -1
3057 || (int) strlen (*mangled) < n)
3058 {
3059 success = 0;
3060 break;
3061 }
3062 string_prependn (&decl, *mangled, n);
3063 *mangled += n;
3064 }
3065 else if (**mangled == 'X' || **mangled == 'Y')
3066 {
3067 string temp;
3068 do_type (work, mangled, &temp);
3069 string_prepends (&decl, &temp);
3070 }
3071 else if (**mangled == 't')
3072 {
3073 string temp;
3074 string_init (&temp);
3075 success = demangle_template (work, mangled, &temp,
3076 NULL, 1, 1);
3077 if (success)
3078 {
3079 string_prependn (&decl, temp.b, temp.p - temp.b);
3080 string_clear (&temp);
3081 }
3082 else
3083 break;
3084 }
3085 else
3086 {
3087 success = 0;
3088 break;
3089 }
3090
3091 string_prepend (&decl, "(");
3092 if (member)
3093 {
3094 switch (**mangled)
3095 {
3096 case 'C':
3097 case 'V':
3098 case 'u':
3099 type_quals |= code_for_qualifier (**mangled);
3100 (*mangled)++;
3101 break;
3102
3103 default:
3104 break;
3105 }
3106
3107 if (*(*mangled)++ != 'F')
3108 {
3109 success = 0;
3110 break;
3111 }
3112 }
3113 if ((member && !demangle_nested_args (work, mangled, &decl))
3114 || **mangled != '_')
3115 {
3116 success = 0;
3117 break;
3118 }
3119 (*mangled)++;
3120 if (! PRINT_ANSI_QUALIFIERS)
3121 {
3122 break;
3123 }
3124 if (type_quals != TYPE_UNQUALIFIED)
3125 {
3126 APPEND_BLANK (&decl);
3127 string_append (&decl, qualifier_string (type_quals));
3128 }
3129 break;
3130 }
3131 case 'G':
3132 (*mangled)++;
3133 break;
3134
3135 case 'C':
3136 case 'V':
3137 case 'u':
3138 if (PRINT_ANSI_QUALIFIERS)
3139 {
3140 if (!STRING_EMPTY (&decl))
3141 string_prepend (&decl, " ");
3142
3143 string_prepend (&decl, demangle_qualifier (**mangled));
3144 }
3145 (*mangled)++;
3146 break;
3147 /*
3148 }
3149 */
3150
3151 /* fall through */
3152 default:
3153 done = 1;
3154 break;
3155 }
3156 }
3157
3158 if (success) switch (**mangled)
3159 {
3160 /* A qualified name, such as "Outer::Inner". */
3161 case 'Q':
3162 case 'K':
3163 {
3164 success = demangle_qualified (work, mangled, result, 0, 1);
3165 break;
3166 }
3167
3168 /* A back reference to a previously seen squangled type */
3169 case 'B':
3170 (*mangled)++;
3171 if (!get_count (mangled, &n) || n >= work -> numb)
3172 success = 0;
3173 else
3174 string_append (result, work->btypevec[n]);
3175 break;
3176
3177 case 'X':
3178 case 'Y':
3179 /* A template parm. We substitute the corresponding argument. */
3180 {
3181 int idx;
3182
3183 (*mangled)++;
3184 idx = consume_count_with_underscores (mangled);
3185
3186 if (idx == -1
3187 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3188 || consume_count_with_underscores (mangled) == -1)
3189 {
3190 success = 0;
3191 break;
3192 }
3193
3194 if (work->tmpl_argvec)
3195 string_append (result, work->tmpl_argvec[idx]);
3196 else
3197 {
3198 char buf[10];
3199 sprintf(buf, "T%d", idx);
3200 string_append (result, buf);
3201 }
3202
3203 success = 1;
3204 }
3205 break;
3206
3207 default:
3208 success = demangle_fund_type (work, mangled, result);
3209 if (tk == tk_none)
3210 tk = (type_kind_t) success;
3211 break;
3212 }
3213
3214 if (success)
3215 {
3216 if (!STRING_EMPTY (&decl))
3217 {
3218 string_append (result, " ");
3219 string_appends (result, &decl);
3220 }
3221 }
3222 else
3223 string_delete (result);
3224 string_delete (&decl);
3225
3226 if (success)
3227 /* Assume an integral type, if we're not sure. */
3228 return (int) ((tk == tk_none) ? tk_integral : tk);
3229 else
3230 return 0;
3231 }
3232
3233 /* Given a pointer to a type string that represents a fundamental type
3234 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3235 string in which the demangled output is being built in RESULT, and
3236 the WORK structure, decode the types and add them to the result.
3237
3238 For example:
3239
3240 "Ci" => "const int"
3241 "Sl" => "signed long"
3242 "CUs" => "const unsigned short"
3243
3244 The value returned is really a type_kind_t. */
3245
3246 static int
3247 demangle_fund_type (work, mangled, result)
3248 struct work_stuff *work;
3249 const char **mangled;
3250 string *result;
3251 {
3252 int done = 0;
3253 int success = 1;
3254 char buf[10];
3255 int dec = 0;
3256 string btype;
3257 type_kind_t tk = tk_integral;
3258
3259 string_init (&btype);
3260
3261 /* First pick off any type qualifiers. There can be more than one. */
3262
3263 while (!done)
3264 {
3265 switch (**mangled)
3266 {
3267 case 'C':
3268 case 'V':
3269 case 'u':
3270 if (PRINT_ANSI_QUALIFIERS)
3271 {
3272 if (!STRING_EMPTY (result))
3273 string_prepend (result, " ");
3274 string_prepend (result, demangle_qualifier (**mangled));
3275 }
3276 (*mangled)++;
3277 break;
3278 case 'U':
3279 (*mangled)++;
3280 APPEND_BLANK (result);
3281 string_append (result, "unsigned");
3282 break;
3283 case 'S': /* signed char only */
3284 (*mangled)++;
3285 APPEND_BLANK (result);
3286 string_append (result, "signed");
3287 break;
3288 case 'J':
3289 (*mangled)++;
3290 APPEND_BLANK (result);
3291 string_append (result, "__complex");
3292 break;
3293 default:
3294 done = 1;
3295 break;
3296 }
3297 }
3298
3299 /* Now pick off the fundamental type. There can be only one. */
3300
3301 switch (**mangled)
3302 {
3303 case '\0':
3304 case '_':
3305 break;
3306 case 'v':
3307 (*mangled)++;
3308 APPEND_BLANK (result);
3309 string_append (result, "void");
3310 break;
3311 case 'x':
3312 (*mangled)++;
3313 APPEND_BLANK (result);
3314 string_append (result, "long long");
3315 break;
3316 case 'l':
3317 (*mangled)++;
3318 APPEND_BLANK (result);
3319 string_append (result, "long");
3320 break;
3321 case 'i':
3322 (*mangled)++;
3323 APPEND_BLANK (result);
3324 string_append (result, "int");
3325 break;
3326 case 's':
3327 (*mangled)++;
3328 APPEND_BLANK (result);
3329 string_append (result, "short");
3330 break;
3331 case 'b':
3332 (*mangled)++;
3333 APPEND_BLANK (result);
3334 string_append (result, "bool");
3335 tk = tk_bool;
3336 break;
3337 case 'c':
3338 (*mangled)++;
3339 APPEND_BLANK (result);
3340 string_append (result, "char");
3341 tk = tk_char;
3342 break;
3343 case 'w':
3344 (*mangled)++;
3345 APPEND_BLANK (result);
3346 string_append (result, "wchar_t");
3347 tk = tk_char;
3348 break;
3349 case 'r':
3350 (*mangled)++;
3351 APPEND_BLANK (result);
3352 string_append (result, "long double");
3353 tk = tk_real;
3354 break;
3355 case 'd':
3356 (*mangled)++;
3357 APPEND_BLANK (result);
3358 string_append (result, "double");
3359 tk = tk_real;
3360 break;
3361 case 'f':
3362 (*mangled)++;
3363 APPEND_BLANK (result);
3364 string_append (result, "float");
3365 tk = tk_real;
3366 break;
3367 case 'G':
3368 (*mangled)++;
3369 if (!isdigit ((unsigned char)**mangled))
3370 {
3371 success = 0;
3372 break;
3373 }
3374 case 'I':
3375 ++(*mangled);
3376 if (**mangled == '_')
3377 {
3378 int i;
3379 ++(*mangled);
3380 for (i = 0; **mangled && **mangled != '_'; ++(*mangled), ++i)
3381 buf[i] = **mangled;
3382 buf[i] = '\0';
3383 ++(*mangled);
3384 }
3385 else
3386 {
3387 strncpy (buf, *mangled, 2);
3388 *mangled += 2;
3389 }
3390 sscanf (buf, "%x", &dec);
3391 sprintf (buf, "int%i_t", dec);
3392 APPEND_BLANK (result);
3393 string_append (result, buf);
3394 break;
3395
3396 /* fall through */
3397 /* An explicit type, such as "6mytype" or "7integer" */
3398 case '0':
3399 case '1':
3400 case '2':
3401 case '3':
3402 case '4':
3403 case '5':
3404 case '6':
3405 case '7':
3406 case '8':
3407 case '9':
3408 {
3409 int bindex = register_Btype (work);
3410 string btype;
3411 string_init (&btype);
3412 if (demangle_class_name (work, mangled, &btype)) {
3413 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3414 APPEND_BLANK (result);
3415 string_appends (result, &btype);
3416 }
3417 else
3418 success = 0;
3419 string_delete (&btype);
3420 break;
3421 }
3422 case 't':
3423 {
3424 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3425 string_appends (result, &btype);
3426 break;
3427 }
3428 default:
3429 success = 0;
3430 break;
3431 }
3432
3433 return success ? ((int) tk) : 0;
3434 }
3435
3436
3437 /* Handle a template's value parameter for HP aCC (extension from ARM)
3438 **mangled points to 'S' or 'U' */
3439
3440 static int
3441 do_hpacc_template_const_value (work, mangled, result)
3442 struct work_stuff *work;
3443 const char **mangled;
3444 string *result;
3445 {
3446 int unsigned_const;
3447
3448 if (**mangled != 'U' && **mangled != 'S')
3449 return 0;
3450
3451 unsigned_const = (**mangled == 'U');
3452
3453 (*mangled)++;
3454
3455 switch (**mangled)
3456 {
3457 case 'N':
3458 string_append (result, "-");
3459 /* fall through */
3460 case 'P':
3461 (*mangled)++;
3462 break;
3463 case 'M':
3464 /* special case for -2^31 */
3465 string_append (result, "-2147483648");
3466 (*mangled)++;
3467 return 1;
3468 default:
3469 return 0;
3470 }
3471
3472 /* We have to be looking at an integer now */
3473 if (!(isdigit ((unsigned char)**mangled)))
3474 return 0;
3475
3476 /* We only deal with integral values for template
3477 parameters -- so it's OK to look only for digits */
3478 while (isdigit ((unsigned char)**mangled))
3479 {
3480 char_str[0] = **mangled;
3481 string_append (result, char_str);
3482 (*mangled)++;
3483 }
3484
3485 if (unsigned_const)
3486 string_append (result, "U");
3487
3488 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3489 with L or LL suffixes. pai/1997-09-03 */
3490
3491 return 1; /* success */
3492 }
3493
3494 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3495 **mangled is pointing to the 'A' */
3496
3497 static int
3498 do_hpacc_template_literal (work, mangled, result)
3499 struct work_stuff *work;
3500 const char **mangled;
3501 string *result;
3502 {
3503 int literal_len = 0;
3504 char * recurse;
3505 char * recurse_dem;
3506
3507 if (**mangled != 'A')
3508 return 0;
3509
3510 (*mangled)++;
3511
3512 literal_len = consume_count (mangled);
3513
3514 if (literal_len <= 0)
3515 return 0;
3516
3517 /* Literal parameters are names of arrays, functions, etc. and the
3518 canonical representation uses the address operator */
3519 string_append (result, "&");
3520
3521 /* Now recursively demangle the literal name */
3522 recurse = (char *) xmalloc (literal_len + 1);
3523 memcpy (recurse, *mangled, literal_len);
3524 recurse[literal_len] = '\000';
3525
3526 recurse_dem = cplus_demangle (recurse, work->options);
3527
3528 if (recurse_dem)
3529 {
3530 string_append (result, recurse_dem);
3531 free (recurse_dem);
3532 }
3533 else
3534 {
3535 string_appendn (result, *mangled, literal_len);
3536 }
3537 (*mangled) += literal_len;
3538 free (recurse);
3539
3540 return 1;
3541 }
3542
3543 static int
3544 snarf_numeric_literal (args, arg)
3545 const char ** args;
3546 string * arg;
3547 {
3548 if (**args == '-')
3549 {
3550 char_str[0] = '-';
3551 string_append (arg, char_str);
3552 (*args)++;
3553 }
3554 else if (**args == '+')
3555 (*args)++;
3556
3557 if (!isdigit ((unsigned char)**args))
3558 return 0;
3559
3560 while (isdigit ((unsigned char)**args))
3561 {
3562 char_str[0] = **args;
3563 string_append (arg, char_str);
3564 (*args)++;
3565 }
3566
3567 return 1;
3568 }
3569
3570 /* Demangle the next argument, given by MANGLED into RESULT, which
3571 *should be an uninitialized* string. It will be initialized here,
3572 and free'd should anything go wrong. */
3573
3574 static int
3575 do_arg (work, mangled, result)
3576 struct work_stuff *work;
3577 const char **mangled;
3578 string *result;
3579 {
3580 /* Remember where we started so that we can record the type, for
3581 non-squangling type remembering. */
3582 const char *start = *mangled;
3583
3584 string_init (result);
3585
3586 if (work->nrepeats > 0)
3587 {
3588 --work->nrepeats;
3589
3590 if (work->previous_argument == 0)
3591 return 0;
3592
3593 /* We want to reissue the previous type in this argument list. */
3594 string_appends (result, work->previous_argument);
3595 return 1;
3596 }
3597
3598 if (**mangled == 'n')
3599 {
3600 /* A squangling-style repeat. */
3601 (*mangled)++;
3602 work->nrepeats = consume_count(mangled);
3603
3604 if (work->nrepeats <= 0)
3605 /* This was not a repeat count after all. */
3606 return 0;
3607
3608 if (work->nrepeats > 9)
3609 {
3610 if (**mangled != '_')
3611 /* The repeat count should be followed by an '_' in this
3612 case. */
3613 return 0;
3614 else
3615 (*mangled)++;
3616 }
3617
3618 /* Now, the repeat is all set up. */
3619 return do_arg (work, mangled, result);
3620 }
3621
3622 /* Save the result in WORK->previous_argument so that we can find it
3623 if it's repeated. Note that saving START is not good enough: we
3624 do not want to add additional types to the back-referenceable
3625 type vector when processing a repeated type. */
3626 if (work->previous_argument)
3627 string_clear (work->previous_argument);
3628 else
3629 {
3630 work->previous_argument = (string*) xmalloc (sizeof (string));
3631 string_init (work->previous_argument);
3632 }
3633
3634 if (!do_type (work, mangled, work->previous_argument))
3635 return 0;
3636
3637 string_appends (result, work->previous_argument);
3638
3639 remember_type (work, start, *mangled - start);
3640 return 1;
3641 }
3642
3643 static void
3644 remember_type (work, start, len)
3645 struct work_stuff *work;
3646 const char *start;
3647 int len;
3648 {
3649 char *tem;
3650
3651 if (work->forgetting_types)
3652 return;
3653
3654 if (work -> ntypes >= work -> typevec_size)
3655 {
3656 if (work -> typevec_size == 0)
3657 {
3658 work -> typevec_size = 3;
3659 work -> typevec
3660 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3661 }
3662 else
3663 {
3664 work -> typevec_size *= 2;
3665 work -> typevec
3666 = (char **) xrealloc ((char *)work -> typevec,
3667 sizeof (char *) * work -> typevec_size);
3668 }
3669 }
3670 tem = xmalloc (len + 1);
3671 memcpy (tem, start, len);
3672 tem[len] = '\0';
3673 work -> typevec[work -> ntypes++] = tem;
3674 }
3675
3676
3677 /* Remember a K type class qualifier. */
3678 static void
3679 remember_Ktype (work, start, len)
3680 struct work_stuff *work;
3681 const char *start;
3682 int len;
3683 {
3684 char *tem;
3685
3686 if (work -> numk >= work -> ksize)
3687 {
3688 if (work -> ksize == 0)
3689 {
3690 work -> ksize = 5;
3691 work -> ktypevec
3692 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3693 }
3694 else
3695 {
3696 work -> ksize *= 2;
3697 work -> ktypevec
3698 = (char **) xrealloc ((char *)work -> ktypevec,
3699 sizeof (char *) * work -> ksize);
3700 }
3701 }
3702 tem = xmalloc (len + 1);
3703 memcpy (tem, start, len);
3704 tem[len] = '\0';
3705 work -> ktypevec[work -> numk++] = tem;
3706 }
3707
3708 /* Register a B code, and get an index for it. B codes are registered
3709 as they are seen, rather than as they are completed, so map<temp<char> >
3710 registers map<temp<char> > as B0, and temp<char> as B1 */
3711
3712 static int
3713 register_Btype (work)
3714 struct work_stuff *work;
3715 {
3716 int ret;
3717
3718 if (work -> numb >= work -> bsize)
3719 {
3720 if (work -> bsize == 0)
3721 {
3722 work -> bsize = 5;
3723 work -> btypevec
3724 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3725 }
3726 else
3727 {
3728 work -> bsize *= 2;
3729 work -> btypevec
3730 = (char **) xrealloc ((char *)work -> btypevec,
3731 sizeof (char *) * work -> bsize);
3732 }
3733 }
3734 ret = work -> numb++;
3735 work -> btypevec[ret] = NULL;
3736 return(ret);
3737 }
3738
3739 /* Store a value into a previously registered B code type. */
3740
3741 static void
3742 remember_Btype (work, start, len, index)
3743 struct work_stuff *work;
3744 const char *start;
3745 int len, index;
3746 {
3747 char *tem;
3748
3749 tem = xmalloc (len + 1);
3750 memcpy (tem, start, len);
3751 tem[len] = '\0';
3752 work -> btypevec[index] = tem;
3753 }
3754
3755 /* Lose all the info related to B and K type codes. */
3756 static void
3757 forget_B_and_K_types (work)
3758 struct work_stuff *work;
3759 {
3760 int i;
3761
3762 while (work -> numk > 0)
3763 {
3764 i = --(work -> numk);
3765 if (work -> ktypevec[i] != NULL)
3766 {
3767 free (work -> ktypevec[i]);
3768 work -> ktypevec[i] = NULL;
3769 }
3770 }
3771
3772 while (work -> numb > 0)
3773 {
3774 i = --(work -> numb);
3775 if (work -> btypevec[i] != NULL)
3776 {
3777 free (work -> btypevec[i]);
3778 work -> btypevec[i] = NULL;
3779 }
3780 }
3781 }
3782 /* Forget the remembered types, but not the type vector itself. */
3783
3784 static void
3785 forget_types (work)
3786 struct work_stuff *work;
3787 {
3788 int i;
3789
3790 while (work -> ntypes > 0)
3791 {
3792 i = --(work -> ntypes);
3793 if (work -> typevec[i] != NULL)
3794 {
3795 free (work -> typevec[i]);
3796 work -> typevec[i] = NULL;
3797 }
3798 }
3799 }
3800
3801 /* Process the argument list part of the signature, after any class spec
3802 has been consumed, as well as the first 'F' character (if any). For
3803 example:
3804
3805 "__als__3fooRT0" => process "RT0"
3806 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3807
3808 DECLP must be already initialised, usually non-empty. It won't be freed
3809 on failure.
3810
3811 Note that g++ differs significantly from ARM and lucid style mangling
3812 with regards to references to previously seen types. For example, given
3813 the source fragment:
3814
3815 class foo {
3816 public:
3817 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3818 };
3819
3820 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3821 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3822
3823 g++ produces the names:
3824
3825 __3fooiRT0iT2iT2
3826 foo__FiR3fooiT1iT1
3827
3828 while lcc (and presumably other ARM style compilers as well) produces:
3829
3830 foo__FiR3fooT1T2T1T2
3831 __ct__3fooFiR3fooT1T2T1T2
3832
3833 Note that g++ bases its type numbers starting at zero and counts all
3834 previously seen types, while lucid/ARM bases its type numbers starting
3835 at one and only considers types after it has seen the 'F' character
3836 indicating the start of the function args. For lucid/ARM style, we
3837 account for this difference by discarding any previously seen types when
3838 we see the 'F' character, and subtracting one from the type number
3839 reference.
3840
3841 */
3842
3843 static int
3844 demangle_args (work, mangled, declp)
3845 struct work_stuff *work;
3846 const char **mangled;
3847 string *declp;
3848 {
3849 string arg;
3850 int need_comma = 0;
3851 int r;
3852 int t;
3853 const char *tem;
3854 char temptype;
3855
3856 if (PRINT_ARG_TYPES)
3857 {
3858 string_append (declp, "(");
3859 if (**mangled == '\0')
3860 {
3861 string_append (declp, "void");
3862 }
3863 }
3864
3865 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3866 || work->nrepeats > 0)
3867 {
3868 if ((**mangled == 'N') || (**mangled == 'T'))
3869 {
3870 temptype = *(*mangled)++;
3871
3872 if (temptype == 'N')
3873 {
3874 if (!get_count (mangled, &r))
3875 {
3876 return (0);
3877 }
3878 }
3879 else
3880 {
3881 r = 1;
3882 }
3883 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3884 {
3885 /* If we have 10 or more types we might have more than a 1 digit
3886 index so we'll have to consume the whole count here. This
3887 will lose if the next thing is a type name preceded by a
3888 count but it's impossible to demangle that case properly
3889 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3890 Pc, ...)" or "(..., type12, char *, ...)" */
3891 if ((t = consume_count(mangled)) <= 0)
3892 {
3893 return (0);
3894 }
3895 }
3896 else
3897 {
3898 if (!get_count (mangled, &t))
3899 {
3900 return (0);
3901 }
3902 }
3903 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3904 {
3905 t--;
3906 }
3907 /* Validate the type index. Protect against illegal indices from
3908 malformed type strings. */
3909 if ((t < 0) || (t >= work -> ntypes))
3910 {
3911 return (0);
3912 }
3913 while (work->nrepeats > 0 || --r >= 0)
3914 {
3915 tem = work -> typevec[t];
3916 if (need_comma && PRINT_ARG_TYPES)
3917 {
3918 string_append (declp, ", ");
3919 }
3920 if (!do_arg (work, &tem, &arg))
3921 {
3922 return (0);
3923 }
3924 if (PRINT_ARG_TYPES)
3925 {
3926 string_appends (declp, &arg);
3927 }
3928 string_delete (&arg);
3929 need_comma = 1;
3930 }
3931 }
3932 else
3933 {
3934 if (need_comma && PRINT_ARG_TYPES)
3935 string_append (declp, ", ");
3936 if (!do_arg (work, mangled, &arg))
3937 return (0);
3938 if (PRINT_ARG_TYPES)
3939 string_appends (declp, &arg);
3940 string_delete (&arg);
3941 need_comma = 1;
3942 }
3943 }
3944
3945 if (**mangled == 'e')
3946 {
3947 (*mangled)++;
3948 if (PRINT_ARG_TYPES)
3949 {
3950 if (need_comma)
3951 {
3952 string_append (declp, ",");
3953 }
3954 string_append (declp, "...");
3955 }
3956 }
3957
3958 if (PRINT_ARG_TYPES)
3959 {
3960 string_append (declp, ")");
3961 }
3962 return (1);
3963 }
3964
3965 /* Like demangle_args, but for demangling the argument lists of function
3966 and method pointers or references, not top-level declarations. */
3967
3968 static int
3969 demangle_nested_args (work, mangled, declp)
3970 struct work_stuff *work;
3971 const char **mangled;
3972 string *declp;
3973 {
3974 string* saved_previous_argument;
3975 int result;
3976 int saved_nrepeats;
3977
3978 /* The G++ name-mangling algorithm does not remember types on nested
3979 argument lists, unless -fsquangling is used, and in that case the
3980 type vector updated by remember_type is not used. So, we turn
3981 off remembering of types here. */
3982 ++work->forgetting_types;
3983
3984 /* For the repeat codes used with -fsquangling, we must keep track of
3985 the last argument. */
3986 saved_previous_argument = work->previous_argument;
3987 saved_nrepeats = work->nrepeats;
3988 work->previous_argument = 0;
3989 work->nrepeats = 0;
3990
3991 /* Actually demangle the arguments. */
3992 result = demangle_args (work, mangled, declp);
3993
3994 /* Restore the previous_argument field. */
3995 if (work->previous_argument)
3996 string_delete (work->previous_argument);
3997 work->previous_argument = saved_previous_argument;
3998 --work->forgetting_types;
3999 work->nrepeats = saved_nrepeats;
4000
4001 return result;
4002 }
4003
4004 static void
4005 demangle_function_name (work, mangled, declp, scan)
4006 struct work_stuff *work;
4007 const char **mangled;
4008 string *declp;
4009 const char *scan;
4010 {
4011 size_t i;
4012 string type;
4013 const char *tem;
4014
4015 string_appendn (declp, (*mangled), scan - (*mangled));
4016 string_need (declp, 1);
4017 *(declp -> p) = '\0';
4018
4019 /* Consume the function name, including the "__" separating the name
4020 from the signature. We are guaranteed that SCAN points to the
4021 separator. */
4022
4023 (*mangled) = scan + 2;
4024 /* We may be looking at an instantiation of a template function:
4025 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4026 following _F marks the start of the function arguments. Handle
4027 the template arguments first. */
4028
4029 if (HP_DEMANGLING && (**mangled == 'X'))
4030 {
4031 demangle_arm_hp_template (work, mangled, 0, declp);
4032 /* This leaves MANGLED pointing to the 'F' marking func args */
4033 }
4034
4035 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4036 {
4037
4038 /* See if we have an ARM style constructor or destructor operator.
4039 If so, then just record it, clear the decl, and return.
4040 We can't build the actual constructor/destructor decl until later,
4041 when we recover the class name from the signature. */
4042
4043 if (strcmp (declp -> b, "__ct") == 0)
4044 {
4045 work -> constructor += 1;
4046 string_clear (declp);
4047 return;
4048 }
4049 else if (strcmp (declp -> b, "__dt") == 0)
4050 {
4051 work -> destructor += 1;
4052 string_clear (declp);
4053 return;
4054 }
4055 }
4056
4057 if (declp->p - declp->b >= 3
4058 && declp->b[0] == 'o'
4059 && declp->b[1] == 'p'
4060 && strchr (cplus_markers, declp->b[2]) != NULL)
4061 {
4062 /* see if it's an assignment expression */
4063 if (declp->p - declp->b >= 10 /* op$assign_ */
4064 && memcmp (declp->b + 3, "assign_", 7) == 0)
4065 {
4066 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4067 {
4068 int len = declp->p - declp->b - 10;
4069 if ((int) strlen (optable[i].in) == len
4070 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4071 {
4072 string_clear (declp);
4073 string_append (declp, "operator");
4074 string_append (declp, optable[i].out);
4075 string_append (declp, "=");
4076 break;
4077 }
4078 }
4079 }
4080 else
4081 {
4082 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4083 {
4084 int len = declp->p - declp->b - 3;
4085 if ((int) strlen (optable[i].in) == len
4086 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4087 {
4088 string_clear (declp);
4089 string_append (declp, "operator");
4090 string_append (declp, optable[i].out);
4091 break;
4092 }
4093 }
4094 }
4095 }
4096 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4097 && strchr (cplus_markers, declp->b[4]) != NULL)
4098 {
4099 /* type conversion operator */
4100 tem = declp->b + 5;
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] == 'o' && declp->b[3] == 'p')
4111 {
4112 /* ANSI. */
4113 /* type conversion operator. */
4114 tem = declp->b + 4;
4115 if (do_type (work, &tem, &type))
4116 {
4117 string_clear (declp);
4118 string_append (declp, "operator ");
4119 string_appends (declp, &type);
4120 string_delete (&type);
4121 }
4122 }
4123 else if (declp->b[0] == '_' && declp->b[1] == '_'
4124 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4125 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4126 {
4127 if (declp->b[4] == '\0')
4128 {
4129 /* Operator. */
4130 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4131 {
4132 if (strlen (optable[i].in) == 2
4133 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4134 {
4135 string_clear (declp);
4136 string_append (declp, "operator");
4137 string_append (declp, optable[i].out);
4138 break;
4139 }
4140 }
4141 }
4142 else
4143 {
4144 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4145 {
4146 /* Assignment. */
4147 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4148 {
4149 if (strlen (optable[i].in) == 3
4150 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4151 {
4152 string_clear (declp);
4153 string_append (declp, "operator");
4154 string_append (declp, optable[i].out);
4155 break;
4156 }
4157 }
4158 }
4159 }
4160 }
4161 }
4162
4163 /* a mini string-handling package */
4164
4165 static void
4166 string_need (s, n)
4167 string *s;
4168 int n;
4169 {
4170 int tem;
4171
4172 if (s->b == NULL)
4173 {
4174 if (n < 32)
4175 {
4176 n = 32;
4177 }
4178 s->p = s->b = xmalloc (n);
4179 s->e = s->b + n;
4180 }
4181 else if (s->e - s->p < n)
4182 {
4183 tem = s->p - s->b;
4184 n += tem;
4185 n *= 2;
4186 s->b = xrealloc (s->b, n);
4187 s->p = s->b + tem;
4188 s->e = s->b + n;
4189 }
4190 }
4191
4192 static void
4193 string_delete (s)
4194 string *s;
4195 {
4196 if (s->b != NULL)
4197 {
4198 free (s->b);
4199 s->b = s->e = s->p = NULL;
4200 }
4201 }
4202
4203 static void
4204 string_init (s)
4205 string *s;
4206 {
4207 s->b = s->p = s->e = NULL;
4208 }
4209
4210 static void
4211 string_clear (s)
4212 string *s;
4213 {
4214 s->p = s->b;
4215 }
4216
4217 #if 0
4218
4219 static int
4220 string_empty (s)
4221 string *s;
4222 {
4223 return (s->b == s->p);
4224 }
4225
4226 #endif
4227
4228 static void
4229 string_append (p, s)
4230 string *p;
4231 const char *s;
4232 {
4233 int n;
4234 if (s == NULL || *s == '\0')
4235 return;
4236 n = strlen (s);
4237 string_need (p, n);
4238 memcpy (p->p, s, n);
4239 p->p += n;
4240 }
4241
4242 static void
4243 string_appends (p, s)
4244 string *p, *s;
4245 {
4246 int n;
4247
4248 if (s->b != s->p)
4249 {
4250 n = s->p - s->b;
4251 string_need (p, n);
4252 memcpy (p->p, s->b, n);
4253 p->p += n;
4254 }
4255 }
4256
4257 static void
4258 string_appendn (p, s, n)
4259 string *p;
4260 const char *s;
4261 int n;
4262 {
4263 if (n != 0)
4264 {
4265 string_need (p, n);
4266 memcpy (p->p, s, n);
4267 p->p += n;
4268 }
4269 }
4270
4271 static void
4272 string_prepend (p, s)
4273 string *p;
4274 const char *s;
4275 {
4276 if (s != NULL && *s != '\0')
4277 {
4278 string_prependn (p, s, strlen (s));
4279 }
4280 }
4281
4282 static void
4283 string_prepends (p, s)
4284 string *p, *s;
4285 {
4286 if (s->b != s->p)
4287 {
4288 string_prependn (p, s->b, s->p - s->b);
4289 }
4290 }
4291
4292 static void
4293 string_prependn (p, s, n)
4294 string *p;
4295 const char *s;
4296 int n;
4297 {
4298 char *q;
4299
4300 if (n != 0)
4301 {
4302 string_need (p, n);
4303 for (q = p->p - 1; q >= p->b; q--)
4304 {
4305 q[n] = q[0];
4306 }
4307 memcpy (p->b, s, n);
4308 p->p += n;
4309 }
4310 }
4311
4312 /* To generate a standalone demangler program for testing purposes,
4313 just compile and link this file with -DMAIN and libiberty.a. When
4314 run, it demangles each command line arg, or each stdin string, and
4315 prints the result on stdout. */
4316
4317 #ifdef MAIN
4318
4319 #include "getopt.h"
4320
4321 static char *program_name;
4322 static char *program_version = VERSION;
4323 static int flags = DMGL_PARAMS | DMGL_ANSI;
4324
4325 static void demangle_it PARAMS ((char *));
4326 static void usage PARAMS ((FILE *, int));
4327 static void fatal PARAMS ((char *));
4328
4329 static void
4330 demangle_it (mangled_name)
4331 char *mangled_name;
4332 {
4333 char *result;
4334
4335 result = cplus_demangle (mangled_name, flags);
4336 if (result == NULL)
4337 {
4338 printf ("%s\n", mangled_name);
4339 }
4340 else
4341 {
4342 printf ("%s\n", result);
4343 free (result);
4344 }
4345 }
4346
4347 static void
4348 usage (stream, status)
4349 FILE *stream;
4350 int status;
4351 {
4352 fprintf (stream, "\
4353 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4354 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4355 [--help] [--version] [arg...]\n",
4356 program_name);
4357 exit (status);
4358 }
4359
4360 #define MBUF_SIZE 32767
4361 char mbuffer[MBUF_SIZE];
4362
4363 /* Defined in the automatically-generated underscore.c. */
4364 extern int prepends_underscore;
4365
4366 int strip_underscore = 0;
4367
4368 static struct option long_options[] = {
4369 {"strip-underscores", no_argument, 0, '_'},
4370 {"format", required_argument, 0, 's'},
4371 {"help", no_argument, 0, 'h'},
4372 {"java", no_argument, 0, 'j'},
4373 {"no-strip-underscores", no_argument, 0, 'n'},
4374 {"version", no_argument, 0, 'v'},
4375 {0, no_argument, 0, 0}
4376 };
4377
4378 /* More 'friendly' abort that prints the line and file.
4379 config.h can #define abort fancy_abort if you like that sort of thing. */
4380
4381 void
4382 fancy_abort ()
4383 {
4384 fatal ("Internal gcc abort.");
4385 }
4386
4387 int
4388 main (argc, argv)
4389 int argc;
4390 char **argv;
4391 {
4392 char *result;
4393 int c;
4394
4395 program_name = argv[0];
4396
4397 strip_underscore = prepends_underscore;
4398
4399 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4400 {
4401 switch (c)
4402 {
4403 case '?':
4404 usage (stderr, 1);
4405 break;
4406 case 'h':
4407 usage (stdout, 0);
4408 case 'n':
4409 strip_underscore = 0;
4410 break;
4411 case 'v':
4412 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4413 exit (0);
4414 case '_':
4415 strip_underscore = 1;
4416 break;
4417 case 'j':
4418 flags |= DMGL_JAVA;
4419 break;
4420 case 's':
4421 if (strcmp (optarg, "gnu") == 0)
4422 {
4423 current_demangling_style = gnu_demangling;
4424 }
4425 else if (strcmp (optarg, "lucid") == 0)
4426 {
4427 current_demangling_style = lucid_demangling;
4428 }
4429 else if (strcmp (optarg, "arm") == 0)
4430 {
4431 current_demangling_style = arm_demangling;
4432 }
4433 else if (strcmp (optarg, "hp") == 0)
4434 {
4435 current_demangling_style = hp_demangling;
4436 }
4437 else if (strcmp (optarg, "edg") == 0)
4438 {
4439 current_demangling_style = edg_demangling;
4440 }
4441 else
4442 {
4443 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4444 program_name, optarg);
4445 exit (1);
4446 }
4447 break;
4448 }
4449 }
4450
4451 if (optind < argc)
4452 {
4453 for ( ; optind < argc; optind++)
4454 {
4455 demangle_it (argv[optind]);
4456 }
4457 }
4458 else
4459 {
4460 for (;;)
4461 {
4462 int i = 0;
4463 c = getchar ();
4464 /* Try to read a label. */
4465 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.' ||
4466 c == '<' || c == '>' || c == '#' || c == ',' || c == '*' || c == '&' ||
4467 c == '[' || c == ']' || c == ':' || c == '(' || c == ')'))
4468 /* the ones in the 2nd & 3rd lines were added to handle
4469 HP aCC template specialization manglings */
4470 {
4471 if (i >= MBUF_SIZE-1)
4472 break;
4473 mbuffer[i++] = c;
4474 c = getchar ();
4475 }
4476 if (i > 0)
4477 {
4478 int skip_first = 0;
4479
4480 if (mbuffer[0] == '.')
4481 ++skip_first;
4482 if (strip_underscore && mbuffer[skip_first] == '_')
4483 ++skip_first;
4484
4485 if (skip_first > i)
4486 skip_first = i;
4487
4488 mbuffer[i] = 0;
4489
4490 result = cplus_demangle (mbuffer + skip_first, flags);
4491 if (result)
4492 {
4493 if (mbuffer[0] == '.')
4494 putc ('.', stdout);
4495 fputs (result, stdout);
4496 free (result);
4497 }
4498 else
4499 fputs (mbuffer, stdout);
4500
4501 fflush (stdout);
4502 }
4503 if (c == EOF)
4504 break;
4505 putchar (c);
4506 }
4507 }
4508
4509 exit (0);
4510 }
4511
4512 static void
4513 fatal (str)
4514 char *str;
4515 {
4516 fprintf (stderr, "%s: %s\n", program_name, str);
4517 exit (1);
4518 }
4519
4520 PTR
4521 xmalloc (size)
4522 size_t size;
4523 {
4524 register PTR value = (PTR) malloc (size);
4525 if (value == 0)
4526 fatal ("virtual memory exhausted");
4527 return value;
4528 }
4529
4530 PTR
4531 xrealloc (ptr, size)
4532 PTR ptr;
4533 size_t size;
4534 {
4535 register PTR value = (PTR) realloc (ptr, size);
4536 if (value == 0)
4537 fatal ("virtual memory exhausted");
4538 return value;
4539 }
4540 #endif /* main */