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