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