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