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