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