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