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