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