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