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