Changes to support GDB running on DOS using GO32 and H8 support
[deliverable/binutils-gdb.git] / gdb / cplus-dem.c
CommitLineData
dd3b648e 1/* Demangler for GNU C++
7d9884b9 2 Copyright 1989, 1991 Free Software Foundation, Inc.
f9b5584c
FF
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
dd3b648e 5
572acbbe
MT
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
99a7de40 10
572acbbe
MT
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
99a7de40 15
572acbbe
MT
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e 19
f9b5584c 20/* This is for g++ 1.95.03 (November 13 version). */
dd3b648e 21
8f793aa5 22/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
dd3b648e
RP
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
e1ce8aa5
JK
28/* GDB-specific, FIXME. */
29#include "defs.h"
8f793aa5 30#include "demangle.h"
e1ce8aa5 31
d747e0af 32#include <ctype.h>
dd3b648e 33#include <string.h>
dd3b648e 34
f9b5584c
FF
35#if !defined (GNU_DEMANGLING) && !defined (ARM_DEMANGLING)
36# define GNU_DEMANGLING 1
37#endif
38
8ffd75c8
JG
39/* This is '$' on systems where the assembler can deal with that.
40 Where the assembler can't, it's '.' (but on many systems '.' is
41 used for other things). */
f9b5584c 42
8ffd75c8
JG
43#if !defined (CPLUS_MARKER)
44#define CPLUS_MARKER '$'
45#endif
46
dd3b648e
RP
47#ifndef __STDC__
48#define const
49#endif
50
f9b5584c
FF
51/* Stuff that is shared between sub-routines.
52 * Using a shared structure allows cplus_demangle to be reentrant. */
f536aa39 53
f9b5584c
FF
54struct work_stuff
55{
8f793aa5 56 int options;
f536aa39
PB
57 char **typevec;
58 int ntypes;
59 int typevec_size;
f9b5584c
FF
60 int constructor;
61 int destructor;
62 int static_type; /* A static member function */
63 int const_type; /* A const member function */
f536aa39 64};
dd3b648e 65
f9b5584c
FF
66#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
67#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
68
69static const struct optable
70{
dd3b648e
RP
71 const char *in;
72 const char *out;
8f793aa5 73 int flags;
dd3b648e 74} optable[] = {
8f793aa5
FF
75 "nw", " new", DMGL_ANSI, /* new (1.92, ansi) */
76 "dl", " delete", DMGL_ANSI, /* new (1.92, ansi) */
77 "new", " new", 0, /* old (1.91, and 1.x) */
78 "delete", " delete", 0, /* old (1.91, and 1.x) */
79 "as", "=", DMGL_ANSI, /* ansi */
80 "ne", "!=", DMGL_ANSI, /* old, ansi */
81 "eq", "==", DMGL_ANSI, /* old, ansi */
82 "ge", ">=", DMGL_ANSI, /* old, ansi */
83 "gt", ">", DMGL_ANSI, /* old, ansi */
84 "le", "<=", DMGL_ANSI, /* old, ansi */
85 "lt", "<", DMGL_ANSI, /* old, ansi */
86 "plus", "+", 0, /* old */
87 "pl", "+", DMGL_ANSI, /* ansi */
88 "apl", "+=", DMGL_ANSI, /* ansi */
89 "minus", "-", 0, /* old */
90 "mi", "-", DMGL_ANSI, /* ansi */
91 "ami", "-=", DMGL_ANSI, /* ansi */
92 "mult", "*", 0, /* old */
93 "ml", "*", DMGL_ANSI, /* ansi */
f9b5584c
FF
94#ifdef ARM_DEMANGLING
95 "amu", "*=", DMGL_ANSI, /* ansi */
96#else
8f793aa5 97 "aml", "*=", DMGL_ANSI, /* ansi */
f9b5584c 98#endif
8f793aa5
FF
99 "convert", "+", 0, /* old (unary +) */
100 "negate", "-", 0, /* old (unary -) */
101 "trunc_mod", "%", 0, /* old */
102 "md", "%", DMGL_ANSI, /* ansi */
103 "amd", "%=", DMGL_ANSI, /* ansi */
104 "trunc_div", "/", 0, /* old */
105 "dv", "/", DMGL_ANSI, /* ansi */
106 "adv", "/=", DMGL_ANSI, /* ansi */
107 "truth_andif", "&&", 0, /* old */
108 "aa", "&&", DMGL_ANSI, /* ansi */
109 "truth_orif", "||", 0, /* old */
110 "oo", "||", DMGL_ANSI, /* ansi */
111 "truth_not", "!", 0, /* old */
112 "nt", "!", DMGL_ANSI, /* ansi */
113 "postincrement","++", 0, /* old */
114 "pp", "++", DMGL_ANSI, /* ansi */
115 "postdecrement","--", 0, /* old */
116 "mm", "--", DMGL_ANSI, /* ansi */
117 "bit_ior", "|", 0, /* old */
118 "or", "|", DMGL_ANSI, /* ansi */
119 "aor", "|=", DMGL_ANSI, /* ansi */
120 "bit_xor", "^", 0, /* old */
121 "er", "^", DMGL_ANSI, /* ansi */
122 "aer", "^=", DMGL_ANSI, /* ansi */
123 "bit_and", "&", 0, /* old */
124 "ad", "&", DMGL_ANSI, /* ansi */
125 "aad", "&=", DMGL_ANSI, /* ansi */
126 "bit_not", "~", 0, /* old */
127 "co", "~", DMGL_ANSI, /* ansi */
128 "call", "()", 0, /* old */
129 "cl", "()", DMGL_ANSI, /* ansi */
130 "alshift", "<<", 0, /* old */
131 "ls", "<<", DMGL_ANSI, /* ansi */
132 "als", "<<=", DMGL_ANSI, /* ansi */
133 "arshift", ">>", 0, /* old */
134 "rs", ">>", DMGL_ANSI, /* ansi */
135 "ars", ">>=", DMGL_ANSI, /* ansi */
136 "component", "->", 0, /* old */
f9b5584c
FF
137#ifdef LUCID_DEMANGLING
138 "pt", "->", DMGL_ANSI, /* ansi; Lucid C++ form */
139#else
8f793aa5 140 "rf", "->", DMGL_ANSI, /* ansi */
f9b5584c 141#endif
8f793aa5
FF
142 "indirect", "*", 0, /* old */
143 "method_call", "->()", 0, /* old */
144 "addr", "&", 0, /* old (unary &) */
145 "array", "[]", 0, /* old */
146 "vc", "[]", DMGL_ANSI, /* ansi */
147 "compound", ", ", 0, /* old */
148 "cm", ", ", DMGL_ANSI, /* ansi */
149 "cond", "?:", 0, /* old */
150 "cn", "?:", DMGL_ANSI, /* psuedo-ansi */
151 "max", ">?", 0, /* old */
152 "mx", ">?", DMGL_ANSI, /* psuedo-ansi */
153 "min", "<?", 0, /* old */
154 "mn", "<?", DMGL_ANSI, /* psuedo-ansi */
155 "nop", "", 0, /* old (for operator=) */
156 "rm", "->*", DMGL_ANSI, /* ansi */
dd3b648e
RP
157};
158
dd3b648e 159
f9b5584c
FF
160typedef struct string /* Beware: these aren't required to be */
161{ /* '\0' terminated. */
dd3b648e
RP
162 char *b; /* pointer to start of string */
163 char *p; /* pointer after last character */
164 char *e; /* pointer after end of allocated space */
165} string;
166
f9b5584c
FF
167#define STRING_EMPTY(str) ((str) -> b == (str) -> p)
168#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
169 string_prepend(str, " ");}
170#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
171 string_append(str, " ");}
172
173/* Prototypes for local functions */
174
175static char *
176mop_up PARAMS ((string *, struct work_stuff *, int));
177
178static int
179demangle_method_args PARAMS ((string *, const char **, struct work_stuff *));
180
181static int
182demangle_template PARAMS ((string *declp, const char **, struct work_stuff *));
183
184static int
185demangle_qualified PARAMS ((string *, const char **, struct work_stuff *));
186
187static int
188demangle_class PARAMS ((string *, const char **, struct work_stuff *));
189
190static int
191demangle_fund_type PARAMS ((const char **, string *, struct work_stuff *));
192
193static int
194demangle_signature PARAMS ((string *, const char **, struct work_stuff *));
195
196static int
197demangle_prefix PARAMS ((string *, const char **, struct work_stuff *));
198
199static int
200gnu_special PARAMS ((string *, const char **, struct work_stuff *));
201
1ab3bf1b
JG
202static void
203string_need PARAMS ((string *, int));
204
205static void
206string_delete PARAMS ((string *));
207
208static void
209string_init PARAMS ((string *));
210
211static void
212string_clear PARAMS ((string *));
213
214static int
215string_empty PARAMS ((string *));
216
217static void
218string_append PARAMS ((string *, const char *));
219
220static void
221string_appends PARAMS ((string *, string *));
222
223static void
224string_appendn PARAMS ((string *, const char *, int));
225
226static void
227string_prepend PARAMS ((string *, const char *));
228
229static void
230string_prependn PARAMS ((string *, const char *, int));
231
232static int
233get_count PARAMS ((const char **, int *));
234
235static int
f9b5584c 236demangle_args PARAMS ((string *, const char **, struct work_stuff *));
1ab3bf1b
JG
237
238static int
f536aa39 239do_type PARAMS ((const char **, string *, struct work_stuff *));
1ab3bf1b
JG
240
241static int
f536aa39 242do_arg PARAMS ((const char **, string *, struct work_stuff*));
1ab3bf1b
JG
243
244static void
f9b5584c
FF
245demangle_function_name PARAMS ((string *, const char **, struct work_stuff*,
246 const char *));
1ab3bf1b
JG
247
248static void
f536aa39 249remember_type PARAMS ((const char *, int, struct work_stuff *));
1ab3bf1b 250
dd3b648e 251#if 0
1ab3bf1b
JG
252static void
253string_prepends PARAMS ((string *, string *));
dd3b648e
RP
254#endif
255
1ab3bf1b 256
55838914 257/* Takes operator name as e.g. "++" and returns mangled
572acbbe
MT
258 operator name (e.g. "postincrement_expr"), or NULL if not found.
259
8f793aa5
FF
260 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
261 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
262
55838914 263char *
8f793aa5 264cplus_mangle_opname (opname, options)
55838914 265 char *opname;
8f793aa5 266 int options;
55838914 267{
f9b5584c
FF
268 int i;
269 int len;
55838914 270
f9b5584c 271 len = strlen (opname);
8f793aa5 272 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
55838914
JK
273 {
274 if (strlen (optable[i].out) == len
8f793aa5 275 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
55838914 276 && memcmp (optable[i].out, opname, len) == 0)
f9b5584c 277 return ((char *)optable[i].in);
55838914 278 }
f9b5584c 279 return (0);
55838914
JK
280}
281
8f793aa5
FF
282/* char *cplus_demangle (const char *name, int options)
283
284 If NAME is a mangled function name produced by GNU C++, then
285 a pointer to a malloced string giving a C++ representation
286 of the name will be returned; otherwise NULL will be returned.
287 It is the caller's responsibility to free the string which
288 is returned.
289
290 The OPTIONS arg may contain one or more of the following bits:
291
292 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
293 included.
294 DMGL_PARAMS Function parameters are included.
295
296 For example,
297
298 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
299 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
300 cplus_demangle ("foo__1Ai", 0) => "A::foo"
301
302 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
303 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
304 cplus_demangle ("foo__1Afe", 0) => "A::foo"
f9b5584c
FF
305
306 Note that any leading underscores, or other such characters prepended by
307 the compilation system, are presumed to have already been stripped from
308 TYPE. */
8f793aa5 309
dd3b648e 310char *
f9b5584c
FF
311cplus_demangle (mangled, options)
312 const char *mangled;
8f793aa5 313 int options;
dd3b648e
RP
314{
315 string decl;
dd3b648e 316 int success = 0;
f536aa39 317 struct work_stuff work[1];
dd3b648e 318 const char *p;
f9b5584c
FF
319 char *demangled = NULL;
320
321 if ((mangled != NULL) && (*mangled != '\0'))
322 {
323 (void) memset ((char *) work, 0, sizeof (work));
324 work -> options = options;
325
326 string_init (&decl);
327 success = demangle_prefix (&decl, &mangled, work);
328 if (success && (*mangled != '\0'))
329 {
330 success = demangle_signature (&decl, &mangled, work);
331 }
332 demangled = mop_up (&decl, work, success);
333 }
334 return (demangled);
335}
336
337static char *
338mop_up (declp, work, success)
339 string *declp;
340 struct work_stuff *work;
341 int success;
342{
343 int i;
344 char *demangled = NULL;
345
346 /* Discard the remembered types, if any. */
347
348 for (i = 0; i < work -> ntypes; i++)
349 {
350 if (work -> typevec[i] != NULL)
351 {
352 free (work -> typevec[i]);
353 }
354 }
355 if (work -> typevec != NULL)
356 {
357 free ((char *) work -> typevec);
358 }
359
360 /* If demangling was successful, ensure that the demangled string is null
361 terminated and return it. Otherwise, free the demangling decl. */
362
363 if (!success)
364 {
365 string_delete (declp);
366 }
367 else
368 {
369 string_appendn (declp, "", 1);
370 demangled = declp -> b;
371 }
372 return (demangled);
373}
374
375/*
376
377LOCAL FUNCTION
378
379 demangle_signature -- demangle the signature part of a mangled name
380
381SYNOPSIS
382
383 static int
384 demangle_signature (string *declp, const char **mangled,
385 struct work_stuff *work);
386
387DESCRIPTION
388
389 Consume and demangle the signature portion of the mangled name.
390
391 DECLP is the string where demangled output is being built. At
392 entry it contains the demangled root name from the mangled name
393 prefix. I.E. either a demangled operator name or the root function
394 name. In some special cases, it may contain nothing.
395
396 *MANGLED points to the current unconsumed location in the mangled
397 name. As tokens are consumed and demangling is performed, the
398 pointer is updated to continuously point at the next token to
399 be consumed.
400
401 Demangling GNU style mangled names is nasty because there is no
402 explicit token that marks the start of the outermost function
403 argument list.
404*/
405
406static int
407demangle_signature (declp, mangled, work)
408 string *declp;
409 const char **mangled;
410 struct work_stuff *work;
411{
412 int success = 1;
413 int func_done = 0;
414#ifdef GNU_DEMANGLING
415 int expect_func = 0;
416#endif
dd3b648e
RP
417#ifndef LONGERNAMES
418 const char *premangle;
419#endif
420
f9b5584c
FF
421#ifndef LONGERNAMES
422 premangle = *mangled;
dd3b648e 423#endif
f536aa39 424
f9b5584c 425 while (success && (**mangled != '\0'))
dd3b648e 426 {
f9b5584c 427 switch (**mangled)
dd3b648e 428 {
f9b5584c
FF
429 case 'Q':
430 success = demangle_qualified (declp, mangled, work);
431#ifdef GNU_DEMANGLING
432 expect_func = 1;
433#endif
434 break;
435
436 case 'S':
437 /* Static member function */
438 (*mangled)++;
439 work -> static_type = 1;
440 break;
441
442 case 'C':
443 /* a const member function */
444 (*mangled)++;
445 work -> const_type = 1;
446 break;
447
448 case '0': case '1': case '2': case '3': case '4':
449 case '5': case '6': case '7': case '8': case '9':
450 success = demangle_class (declp, mangled, work);
451#ifndef LONGERNAMES
452 if (success)
453 {
454 remember_type (premangle, *mangled - premangle, work);
455 }
456#endif
457#ifdef GNU_DEMANGLING
458 expect_func = 1;
459#endif
460 break;
461
462 case 'F':
463 /* Function */
464 /* ARM style demangling includes a specific 'F' character after
465 the class name. For GNU style, it is just implied. So we can
466 safely just consume any 'F' at this point and be compatible
467 with either style. */
468 func_done = 1;
469 (*mangled)++;
470 success = demangle_args (declp, mangled, work);
471 break;
472
473 case 't':
474 /* Template */
475 success = demangle_template (declp, mangled, work);
476 break;
477
7fd31a84
FF
478 case '_':
479 /* At the outermost level, we cannot have a return type specified,
480 so if we run into another '_' at this point we are dealing with
481 a mangled name that is either bogus, or has been mangled by
482 some algorithm we don't know how to deal with. So just
483 reject the entire demangling. */
484 success = 0;
485 break;
486
f9b5584c
FF
487 default:
488#ifdef GNU_DEMANGLING
489 /* Assume we have stumbled onto the first outermost function
490 argument token, and start processing args. */
491 func_done = 1;
492 success = demangle_args (declp, mangled, work);
493#else
494 /* Non-GNU demanglers use a specific token to mark the start
495 of the outermost function argument tokens. Typically 'F',
496 for ARM-demangling, for example. So if we find something
497 we are not prepared for, it must be an error. */
498 success = 0;
499#endif
500 break;
dd3b648e 501 }
f9b5584c 502#ifdef GNU_DEMANGLING
7fd31a84 503 if (success && expect_func)
dd3b648e 504 {
f9b5584c
FF
505 func_done = 1;
506 success = demangle_args (declp, mangled, work);
dd3b648e 507 }
f9b5584c
FF
508#endif
509 }
510 if (success && !func_done)
511 {
512 /* Even with ARM style demangling, sometimes there is no explicit
513 function argument tokens if the function takes no arguments. */
514 success = demangle_args (declp, mangled, work);
dd3b648e 515 }
f9b5584c
FF
516 if (success && work -> static_type && PRINT_ARG_TYPES)
517 {
518 string_append (declp, " static");
519 }
520 if (success && work -> const_type && PRINT_ARG_TYPES)
521 {
522 string_append (declp, " const");
523 }
524 return (success);
525}
dd3b648e 526
f9b5584c 527#if 0
dd3b648e 528
f9b5584c
FF
529static int
530demangle_method_args (declp, mangled, work)
531 string *declp;
532 const char **mangled;
533 struct work_stuff *work;
534{
535 int success = 0;
536
537 if (work -> static_type)
4c53d9ca 538 {
f9b5584c
FF
539 string_append (declp, *mangled + 1);
540 *mangled += strlen (*mangled);
541 success = 1;
4c53d9ca 542 }
f9b5584c 543 else
dd3b648e 544 {
f9b5584c
FF
545 success = demangle_args (declp, mangled, work);
546 }
547 return (success);
548}
549
550#endif
551
552static int
553demangle_template (declp, mangled, work)
554 string *declp;
555 const char **mangled;
556 struct work_stuff *work;
557{
558 int i;
559 int n;
560 string tname;
561 string trawname;
562 int is_pointer;
563 int is_real;
564 int is_integral;
565 int r;
566 int need_comma = 0;
567 int success = 0;
568 int done;
569 const char *old_p;
570 int symbol_len;
571 string temp;
572
573 (*mangled)++;
574 string_init (&tname);
575 string_init (&trawname);
576 /* get template name */
577 if (!get_count (mangled, &r))
578 {
579 return (0);
580 }
581 string_appendn (&tname, *mangled, r);
582 string_appendn (&trawname, *mangled, r);
583 string_appendn (&trawname, "", 1);
584 *mangled += r;
585 string_append (&tname, "<");
586 /* get size of template parameter list */
587 if (!get_count (mangled, &r))
588 {
589 return (0);
590 }
591 for (i = 0; i < r; i++)
592 {
593 if (need_comma)
dd3b648e 594 {
f9b5584c
FF
595 string_append (&tname, ", ");
596 }
597 /* Z for type parameters */
598 if (**mangled == 'Z')
599 {
600 (*mangled)++;
601 success = do_type (mangled, &temp, work);
602 string_appendn (&temp, "", 1);
603 if (success)
572acbbe 604 {
f9b5584c
FF
605 string_append (&tname, temp.b);
606 }
607 string_delete(&temp);
608 if (!success)
609 {
610 break;
572acbbe 611 }
572acbbe
MT
612 }
613 else
614 {
f9b5584c
FF
615 /* otherwise, value parameter */
616 old_p = *mangled;
617 is_pointer = 0;
618 is_real = 0;
619 is_integral = 0;
620 done = 0;
621 success = do_type (mangled, &temp, work);
622 string_appendn (&temp, "", 1);
623 if (success)
624 {
625 string_append (&tname, temp.b);
626 }
627 string_delete(&temp);
628 if (!success)
629 {
630 break;
631 }
632 string_append (&tname, "=");
633 while (*old_p && !done)
634 {
635 switch (*old_p)
636 {
637 case 'P':
638 case 'R':
639 done = is_pointer = 1;
640 break;
641 case 'C': /* const */
642 case 'S': /* explicitly signed [char] */
643 case 'U': /* unsigned */
644 case 'V': /* volatile */
645 case 'F': /* function */
646 case 'M': /* member function */
647 case 'O': /* ??? */
648 old_p++;
649 continue;
650 case 'Q': /* repetition of following */
651 case 'T': /* remembered type */
652 abort ();
653 break;
654 case 'v': /* void */
655 abort ();
656 break;
657 case 'x': /* long long */
658 case 'l': /* long */
659 case 'i': /* int */
660 case 's': /* short */
661 case 'c': /* char */
662 done = is_integral = 1;
663 break;
664 case 'r': /* long double */
665 case 'd': /* double */
666 case 'f': /* float */
667 done = is_real = 1;
668 break;
669 default:
670 abort ();
671 }
672 }
673 if (is_integral)
674 {
675 if (**mangled == 'm')
676 {
677 string_appendn (&tname, "-", 1);
678 (*mangled)++;
679 }
680 while (isdigit (**mangled))
681 {
682 string_appendn (&tname, *mangled, 1);
683 (*mangled)++;
684 }
685 }
686 else if (is_real)
687 {
688 if (**mangled == 'm')
689 {
690 string_appendn (&tname, "-", 1);
691 (*mangled)++;
692 }
693 while (isdigit (**mangled))
694 {
695 string_appendn (&tname, *mangled, 1);
696 (*mangled)++;
697 }
698 if (**mangled == '.') /* fraction */
699 {
700 string_appendn (&tname, ".", 1);
701 (*mangled)++;
702 while (isdigit (**mangled))
703 {
704 string_appendn (&tname, *mangled, 1);
705 (*mangled)++;
706 }
707 }
708 if (**mangled == 'e') /* exponent */
709 {
710 string_appendn (&tname, "e", 1);
711 (*mangled)++;
712 while (isdigit (**mangled))
713 {
714 string_appendn (&tname, *mangled, 1);
715 (*mangled)++;
716 }
717 }
718 }
719 else if (is_pointer)
720 {
721 if (!get_count (mangled, &symbol_len))
722 {
723 success = 0;
724 break;
725 }
726 string_appendn (&tname, *mangled, symbol_len);
727 *mangled += symbol_len;
728 }
dd3b648e 729 }
f9b5584c
FF
730 need_comma = 1;
731 }
732 string_append (&tname, ">::");
733 if (work -> destructor)
734 {
735 string_append (&tname, "~");
736 }
737 if (work -> constructor || work -> destructor)
738 {
739 string_append (&tname, trawname.b);
740 }
741 string_delete(&trawname);
742
743 if (!success)
744 {
745 string_delete(&tname);
dd3b648e
RP
746 }
747 else
748 {
f9b5584c
FF
749 string_prepend (declp, tname.b);
750 string_delete (&tname);
751
752 if (work -> static_type)
753 {
754 string_append (declp, *mangled + 1);
755 *mangled += strlen (*mangled);
756 success = 1;
757 }
758 else
759 {
760 success = demangle_args (declp, mangled, work);
761 }
dd3b648e 762 }
f9b5584c 763}
dd3b648e 764
f9b5584c
FF
765/*
766
767LOCAL FUNCTION
768
769 demangle_class -- demangle a mangled class sequence
770
771SYNOPSIS
772
773 static int
774 demangle_class (string *declp, const char **mangled,
775 struct work_stuff *work)
776
777DESCRIPTION
778
779 DECLP points to the buffer into which demangling is being done.
780
781 *MANGLED points to the current token to be demangled. On input,
782 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
783 On exit, it points to the next token after the mangled class on
784 success, or the first unconsumed token on failure.
785
786 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
787 we are demangling a constructor or destructor. In this case
788 we prepend "class::class" or "class::~class" to DECLP.
789
790 Otherwise, we prepend "class::" to the current DECLP.
791
792 Reset the constructor/destructor flags once they have been
793 "consumed". This allows demangle_class to be called later during
794 the same demangling, to do normal class demangling.
795
796 Returns 1 if demangling is successful, 0 otherwise.
797
798*/
799
800static int
801demangle_class (declp, mangled, work)
802 string *declp;
803 const char **mangled;
804 struct work_stuff *work;
805{
806 int n;
807 int success = 0;
808
809 n = 0;
810 do
dd3b648e 811 {
f9b5584c
FF
812 n *= 10;
813 n += **mangled - '0';
814 (*mangled)++;
815 }
816 while (isdigit (**mangled));
817 if (strlen (*mangled) >= n)
818 {
819 if (work -> constructor || work -> destructor)
f536aa39 820 {
f9b5584c
FF
821 string_prependn (declp, *mangled, n);
822 if (work -> destructor)
f536aa39 823 {
f9b5584c 824 string_prepend (declp, "~");
f536aa39 825 }
f9b5584c 826 work -> constructor = work -> destructor = 0;
dd3b648e 827 }
f9b5584c
FF
828 string_prepend (declp, "::");
829 string_prependn (declp, *mangled, n);
830 *mangled += n;
831 success = 1;
832 }
833 return (success);
834}
835
836/*
837
838LOCAL FUNCTION
839
840 demangle_prefix -- consume the mangled name prefix and find signature
841
842SYNOPSIS
843
844 static int
845 demangle_prefix (string *declp, const char **mangled,
846 struct work_stuff *work)
847
848DESCRIPTION
849
850 Consume and demangle the prefix of the mangled name.
851
852 DECLP points to the string buffer into which demangled output is
853 placed. On entry, the buffer is empty. On exit it contains
854 the root function name, the demangled operator name, or in some
855 special cases either nothing or the completely demangled result.
856
857 MANGLED points to the current pointer into the mangled name. As each
858 token of the mangled name is consumed, it is updated. Upon entry
859 the current mangled name pointer points to the first character of
860 the mangled name. Upon exit, it should point to the first character
861 of the signature if demangling was successful, or to the first
862 unconsumed character if demangling of the prefix was unsuccessful.
863
864 Returns 1 on success, 0 otherwise.
865 */
866
867static int
868demangle_prefix (declp, mangled, work)
869 string *declp;
870 const char **mangled;
871 struct work_stuff *work;
872{
873 int success = 1;
874 const char *scan;
875
876 if ((scan = strstr (*mangled, "__")) == NULL)
877 {
878 success = gnu_special (declp, mangled, work);
879 }
880 else if (work -> static_type)
881 {
882 if (!isdigit (scan[0]) && (scan[0] != 't'))
dd3b648e 883 {
f9b5584c 884 success = 0;
dd3b648e 885 }
f9b5584c
FF
886 }
887 else if ((scan == *mangled) && (isdigit (scan[2]) || (scan[2] == 'Q')))
888 {
889 /* A GNU style constructor starts with "__<digit>" or "__Q". */
890 work -> constructor = 1;
891 *mangled = scan + 2;
892 }
893 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
894 {
895 /* Mangled name starts with "__". Skip over any leading '_' characters,
896 then find the next "__" that separates the prefix from the signature.
897 */
898 while (*scan == '_')
dd3b648e 899 {
f9b5584c 900 scan++;
dd3b648e 901 }
f9b5584c 902 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
dd3b648e 903 {
f9b5584c
FF
904 /* No separator (I.E. "__not_mangled"), or empty signature
905 (I.E. "__not_mangled_either__") */
906 success = 0;
dd3b648e
RP
907 }
908 else
909 {
f9b5584c 910 demangle_function_name (declp, mangled, work, scan);
4c53d9ca 911 }
f9b5584c
FF
912 }
913 else if (*(scan + 2) != '\0')
914 {
915 /* Mangled name does not start with "__" but does have one somewhere
916 in there with non empty stuff after it. Looks like a global
917 function name. */
918 demangle_function_name (declp, mangled, work, scan);
919 }
920 else
921 {
922 /* Doesn't look like a mangled name */
923 success = 0;
924 }
925 return (success);
926}
4c53d9ca 927
f9b5584c
FF
928static int
929gnu_special (declp, mangled, work)
930 string *declp;
931 const char **mangled;
932 struct work_stuff *work;
933{
934 int n;
935 int success = 1;
936 const char *p;
937
938 if ((*mangled)[0] == '_'
939 && (*mangled)[1] == CPLUS_MARKER
940 && (*mangled)[2] == '_')
941 {
942 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
943 (*mangled) += 3;
944 work -> destructor = 1;
945 }
946 else if (**mangled != '_' && (p = strchr (*mangled, CPLUS_MARKER)) != NULL)
947 {
948#if 0
949 /* static data member */
950 n = strlen (*mangled) + 2;
951 tem = (char *) xmalloc (n);
952 memcpy (tem, *mangled, p - *mangled);
953 strcpy (tem + (p - *mangled), "::");
954 strcpy (tem + (p - *mangled) + 2, p + 1);
955#endif
dd3b648e 956 }
f9b5584c
FF
957 else if ((*mangled)[0] == '_'
958 && (*mangled)[1] == 'v'
959 && (*mangled)[2] == 't'
960 && (*mangled)[3] == CPLUS_MARKER)
dd3b648e 961 {
f9b5584c
FF
962 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
963 and create the decl. Note that we consume the entire mangled
964 input string, which means that demangle_signature has no work
965 to do. */
966 (*mangled) += 4;
967 n = strlen (*mangled);
968 string_appendn (declp, *mangled, n);
969 string_append (declp, " virtual table");
970 (*mangled) += n;
dd3b648e
RP
971 }
972 else
973 {
f9b5584c
FF
974 success = 0;
975 }
976 return (success);
977}
978
979/* Do a qualified name, such as "Q25Outer5Inner" for "Outer::Inner" */
980
981static int
982demangle_qualified (declp, mangled, work)
983 string *declp;
984 const char **mangled;
985 struct work_stuff *work;
986{
987 int n;
988 string class;
989 string tmp;
990 int success = 0;
991
992 n = (*mangled)[1] - '0';
993 if (n >= 0 && n <= 9)
994 {
995 if ((*mangled)[2] == '_')
996 {
997 /* cfront style */
998 (*mangled)++;
999 }
1000 (*mangled) += 2;
1001 string_init (&class);
1002 while (n-- > 0)
1003 {
1004 success = do_type (mangled, &tmp, work);
1005 string_appends (&class, &tmp);
1006 string_append (&class, "::");
1007 if (n == 0 && (work -> constructor || work -> destructor))
1008 {
1009 if (work -> destructor)
1010 {
1011 string_append (&class, "~");
1012 }
1013 string_appends (&class, &tmp);
1014 }
1015 string_delete (&tmp);
1016 }
1017 work -> constructor = work -> destructor = 0;
1018 string_prependn (declp, class.b, class.p - class.b);
1019 string_delete (&class);
dd3b648e 1020 }
f9b5584c 1021 return (success);
dd3b648e
RP
1022}
1023
1024static int
1025get_count (type, count)
1026 const char **type;
1027 int *count;
1028{
f9b5584c
FF
1029 const char *p;
1030 int n;
1031
dd3b648e 1032 if (!isdigit (**type))
f9b5584c
FF
1033 {
1034 return (0);
1035 }
dd3b648e 1036 *count = **type - '0';
f9b5584c 1037 (*type)++;
dd3b648e
RP
1038 /* see flush_repeats in cplus-method.c */
1039 if (isdigit (**type))
1040 {
f9b5584c
FF
1041 p = *type;
1042 n = *count;
dd3b648e
RP
1043 do
1044 {
1045 n *= 10;
1046 n += *p - '0';
f9b5584c 1047 p++;
dd3b648e
RP
1048 }
1049 while (isdigit (*p));
1050 if (*p == '_')
1051 {
1052 *type = p + 1;
1053 *count = n;
1054 }
1055 }
f9b5584c 1056 return (1);
dd3b648e
RP
1057}
1058
1059/* result will be initialised here; it will be freed on failure */
1060
1061static int
f536aa39 1062do_type (type, result, work)
dd3b648e
RP
1063 const char **type;
1064 string *result;
f536aa39 1065 struct work_stuff *work;
dd3b648e
RP
1066{
1067 int n;
1068 int done;
dd3b648e
RP
1069 int success;
1070 string decl;
1071 const char *remembered_type;
f9b5584c
FF
1072 int constp;
1073 int volatilep;
dd3b648e
RP
1074
1075 string_init (&decl);
1076 string_init (result);
1077
1078 done = 0;
1079 success = 1;
1080 while (success && !done)
1081 {
1082 int member;
1083 switch (**type)
1084 {
f9b5584c
FF
1085 /* A qualified name, such as "Outer::Inner". Note qualifier count
1086 is limited to a single digit (0-9 qualifiers). */
55838914
JK
1087 case 'Q':
1088 n = (*type)[1] - '0';
1089 if (n < 0 || n > 9)
f9b5584c
FF
1090 {
1091 success = 0;
1092 }
f536aa39 1093 if ((*type)[2] == '_') /* cfront style */
f9b5584c
FF
1094 {
1095 (*type)++;
1096 }
55838914
JK
1097 *type += 2;
1098 while (n-- > 0)
f9b5584c
FF
1099 {
1100 do_type (type, result, work);
1101 }
55838914
JK
1102 break;
1103
f9b5584c 1104 /* A pointer type */
dd3b648e 1105 case 'P':
f9b5584c 1106 (*type)++;
dd3b648e
RP
1107 string_prepend (&decl, "*");
1108 break;
1109
f9b5584c 1110 /* A reference type */
dd3b648e 1111 case 'R':
f9b5584c 1112 (*type)++;
dd3b648e
RP
1113 string_prepend (&decl, "&");
1114 break;
1115
f9b5584c 1116 /* A back reference to a previously seen type */
dd3b648e 1117 case 'T':
f9b5584c
FF
1118 (*type)++;
1119 if (!get_count (type, &n) || n >= work -> ntypes)
1120 {
1121 success = 0;
1122 }
dd3b648e
RP
1123 else
1124 {
f9b5584c 1125 remembered_type = work -> typevec[n];
dd3b648e
RP
1126 type = &remembered_type;
1127 }
1128 break;
1129
f9b5584c 1130 /* A function */
dd3b648e 1131 case 'F':
f9b5584c
FF
1132 (*type)++;
1133 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
dd3b648e
RP
1134 {
1135 string_prepend (&decl, "(");
1136 string_append (&decl, ")");
1137 }
8f793aa5 1138 /* After picking off the function args, we expect to either find the
f9b5584c
FF
1139 function return type (preceded by an '_') or the end of the
1140 string. */
1141 if (!demangle_args (&decl, type, work)
8f793aa5 1142 || (**type != '_' && **type != '\0'))
f9b5584c
FF
1143 {
1144 success = 0;
1145 }
8f793aa5 1146 if (success && (**type == '_'))
f9b5584c
FF
1147 {
1148 (*type)++;
1149 }
dd3b648e
RP
1150 break;
1151
1152 case 'M':
1153 case 'O':
1154 {
f9b5584c
FF
1155 constp = 0;
1156 volatilep = 0;
dd3b648e
RP
1157
1158 member = **type == 'M';
f9b5584c 1159 (*type)++;
dd3b648e
RP
1160 if (!isdigit (**type))
1161 {
1162 success = 0;
1163 break;
1164 }
1165 n = 0;
1166 do
1167 {
1168 n *= 10;
1169 n += **type - '0';
f9b5584c 1170 (*type)++;
dd3b648e
RP
1171 }
1172 while (isdigit (**type));
1173 if (strlen (*type) < n)
1174 {
1175 success = 0;
1176 break;
1177 }
1178 string_append (&decl, ")");
1179 string_prepend (&decl, "::");
1180 string_prependn (&decl, *type, n);
1181 string_prepend (&decl, "(");
1182 *type += n;
1183 if (member)
1184 {
1185 if (**type == 'C')
1186 {
f9b5584c 1187 (*type)++;
dd3b648e
RP
1188 constp = 1;
1189 }
1190 if (**type == 'V')
1191 {
f9b5584c 1192 (*type)++;
dd3b648e
RP
1193 volatilep = 1;
1194 }
1195 if (*(*type)++ != 'F')
1196 {
1197 success = 0;
1198 break;
1199 }
1200 }
f9b5584c
FF
1201 if ((member && !demangle_args (&decl, type, work))
1202 || **type != '_')
dd3b648e
RP
1203 {
1204 success = 0;
1205 break;
1206 }
f9b5584c 1207 (*type)++;
8f793aa5 1208 if (! PRINT_ANSI_QUALIFIERS)
f9b5584c
FF
1209 {
1210 break;
1211 }
dd3b648e
RP
1212 if (constp)
1213 {
f9b5584c 1214 APPEND_BLANK (&decl);
dd3b648e
RP
1215 string_append (&decl, "const");
1216 }
1217 if (volatilep)
1218 {
f9b5584c 1219 APPEND_BLANK (&decl);
dd3b648e
RP
1220 string_append (&decl, "volatile");
1221 }
1222 break;
1223 }
1224
1225 case 'C':
1226 if ((*type)[1] == 'P')
1227 {
f9b5584c 1228 (*type)++;
8f793aa5 1229 if (PRINT_ANSI_QUALIFIERS)
dd3b648e 1230 {
f9b5584c
FF
1231 if (!STRING_EMPTY (&decl))
1232 {
1233 string_prepend (&decl, " ");
1234 }
dd3b648e
RP
1235 string_prepend (&decl, "const");
1236 }
1237 break;
1238 }
1239
1240 /* fall through */
1241 default:
1242 done = 1;
1243 break;
1244 }
1245 }
1246
f9b5584c
FF
1247 success = demangle_fund_type (type, result, work);
1248
1249 if (success)
1250 {
1251 if (!STRING_EMPTY (&decl))
1252 {
1253 string_append (result, " ");
1254 string_appends (result, &decl);
1255 }
1256 }
1257 else
1258 {
1259 string_delete (result);
1260 }
1261 string_delete (&decl);
1262 return (success);
1263}
1264
1265/* Given a pointer to a type string that represents a fundamental type
1266 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
1267 string in which the demangled output is being built in RESULT, and
1268 the WORK structure, decode the types and add them to the result.
1269
1270 For example:
1271
1272 "Ci" => "const int"
1273 "Sl" => "signed long"
1274 "CUs" => "const unsigned short"
1275
1276 */
1277
1278static int
1279demangle_fund_type (type, result, work)
1280 const char **type;
1281 string *result;
1282 struct work_stuff *work;
1283{
1284 int done = 0;
1285 int success = 1;
1286 int n;
1287
1288 /* First pick off any type qualifiers. There can be more than one. */
1289
1290 while (!done)
dd3b648e
RP
1291 {
1292 switch (**type)
1293 {
f9b5584c
FF
1294 case 'C':
1295 (*type)++;
1296 if (PRINT_ANSI_QUALIFIERS)
1297 {
1298 APPEND_BLANK (result);
1299 string_append (result, "const");
1300 }
1301 break;
1302 case 'U':
1303 (*type)++;
1304 APPEND_BLANK (result);
1305 string_append (result, "unsigned");
1306 break;
1307 case 'S': /* signed char only */
1308 (*type)++;
1309 APPEND_BLANK (result);
1310 string_append (result, "signed");
1311 break;
1312 case 'V':
1313 (*type)++;
1314 if (PRINT_ANSI_QUALIFIERS)
1315 {
1316 APPEND_BLANK (result);
1317 string_append (result, "volatile");
1318 }
1319 break;
1320 default:
1321 done = 1;
1322 break;
dd3b648e
RP
1323 }
1324 }
1325
f9b5584c
FF
1326 /* Now pick off the fundamental type. There can be only one. */
1327
1328 switch (**type)
1329 {
dd3b648e
RP
1330 case '\0':
1331 case '_':
1332 break;
1333 case 'v':
f9b5584c
FF
1334 (*type)++;
1335 APPEND_BLANK (result);
dd3b648e
RP
1336 string_append (result, "void");
1337 break;
1338 case 'x':
f9b5584c
FF
1339 (*type)++;
1340 APPEND_BLANK (result);
dd3b648e
RP
1341 string_append (result, "long long");
1342 break;
1343 case 'l':
f9b5584c
FF
1344 (*type)++;
1345 APPEND_BLANK (result);
dd3b648e
RP
1346 string_append (result, "long");
1347 break;
1348 case 'i':
f9b5584c
FF
1349 (*type)++;
1350 APPEND_BLANK (result);
dd3b648e
RP
1351 string_append (result, "int");
1352 break;
1353 case 's':
f9b5584c
FF
1354 (*type)++;
1355 APPEND_BLANK (result);
dd3b648e
RP
1356 string_append (result, "short");
1357 break;
1358 case 'c':
f9b5584c
FF
1359 (*type)++;
1360 APPEND_BLANK (result);
dd3b648e
RP
1361 string_append (result, "char");
1362 break;
1363 case 'r':
f9b5584c
FF
1364 (*type)++;
1365 APPEND_BLANK (result);
dd3b648e
RP
1366 string_append (result, "long double");
1367 break;
1368 case 'd':
f9b5584c
FF
1369 (*type)++;
1370 APPEND_BLANK (result);
dd3b648e
RP
1371 string_append (result, "double");
1372 break;
1373 case 'f':
f9b5584c
FF
1374 (*type)++;
1375 APPEND_BLANK (result);
dd3b648e
RP
1376 string_append (result, "float");
1377 break;
1378 case 'G':
f9b5584c 1379 (*type)++;
dd3b648e
RP
1380 if (!isdigit (**type))
1381 {
1382 success = 0;
1383 break;
1384 }
1385 /* fall through */
f9b5584c 1386 /* An explicit type, such as "6mytype" or "7integer" */
dd3b648e
RP
1387 case '0':
1388 case '1':
1389 case '2':
1390 case '3':
1391 case '4':
1392 case '5':
1393 case '6':
1394 case '7':
1395 case '8':
1396 case '9':
1397 n = 0;
1398 do
1399 {
1400 n *= 10;
1401 n += **type - '0';
f9b5584c 1402 (*type)++;
dd3b648e
RP
1403 }
1404 while (isdigit (**type));
1405 if (strlen (*type) < n)
1406 {
1407 success = 0;
1408 break;
1409 }
f9b5584c 1410 APPEND_BLANK (result);
dd3b648e
RP
1411 string_appendn (result, *type, n);
1412 *type += n;
1413 break;
1414 default:
1415 success = 0;
1416 break;
1417 }
1418
f9b5584c 1419 return (success);
dd3b648e
RP
1420}
1421
f9b5584c 1422/* `result' will be initialized in do_type; it will be freed on failure */
dd3b648e
RP
1423
1424static int
f536aa39 1425do_arg (type, result, work)
dd3b648e
RP
1426 const char **type;
1427 string *result;
f536aa39 1428 struct work_stuff *work;
dd3b648e
RP
1429{
1430 const char *start = *type;
1431
f536aa39 1432 if (!do_type (type, result, work))
f9b5584c
FF
1433 {
1434 return (0);
1435 }
1436 else
1437 {
1438 remember_type (start, *type - start, work);
1439 return (1);
1440 }
dd3b648e
RP
1441}
1442
1443static void
f536aa39 1444remember_type (start, len, work)
dd3b648e
RP
1445 const char *start;
1446 int len;
f536aa39 1447 struct work_stuff *work;
dd3b648e
RP
1448{
1449 char *tem;
1450
f9b5584c 1451 if (work -> ntypes >= work -> typevec_size)
dd3b648e 1452 {
f9b5584c 1453 if (work -> typevec_size == 0)
dd3b648e 1454 {
f9b5584c
FF
1455 work -> typevec_size = 3;
1456 work -> typevec =
1457 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
dd3b648e
RP
1458 }
1459 else
1460 {
f9b5584c
FF
1461 work -> typevec_size *= 2;
1462 work -> typevec =
1463 (char **) xrealloc ((char *)work -> typevec,
1464 sizeof (char *) * work -> typevec_size);
dd3b648e
RP
1465 }
1466 }
1467 tem = (char *) xmalloc (len + 1);
1468 memcpy (tem, start, len);
1469 tem[len] = '\0';
f9b5584c 1470 work -> typevec[work -> ntypes++] = tem;
dd3b648e
RP
1471}
1472
f9b5584c
FF
1473/* Process the argument list part of the signature, after any class spec
1474 has been consumed, as well as the first 'F' character (if any). For
1475 example:
1476
1477 "__als__3fooRT0" => process "RT0"
1478 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
1479
1480 DECLP must be already initialised, usually non-empty. It won't be freed
1481 on failure */
dd3b648e
RP
1482
1483static int
f9b5584c
FF
1484demangle_args (declp, type, work)
1485 string *declp;
dd3b648e 1486 const char **type;
f536aa39 1487 struct work_stuff *work;
dd3b648e
RP
1488{
1489 string arg;
1490 int need_comma = 0;
f9b5584c
FF
1491 int r;
1492 int t;
1493 const char *tem;
1494 char temptype;
dd3b648e 1495
8f793aa5 1496 if (PRINT_ARG_TYPES)
f9b5584c
FF
1497 {
1498 string_append (declp, "(");
1499 if (**type == '\0')
1500 {
1501 string_append (declp, "void");
1502 }
1503 }
dd3b648e 1504
55b3ef9a 1505 while (**type != '_' && **type != '\0' && **type != 'e')
dd3b648e 1506 {
f9b5584c 1507 if ((**type == 'N') || (**type == 'T'))
dd3b648e 1508 {
f9b5584c
FF
1509 temptype = *(*type)++;
1510
1511 if (temptype == 'N')
1512 {
1513 if (!get_count (type, &r))
1514 {
1515 return (0);
1516 }
1517 }
1518 else
1519 {
1520 r = 1;
1521 }
1522 if (!get_count (type, &t))
1523 {
1524 return (0);
1525 }
1526#ifdef ARM_DEMANGLING
1527 t--;
1528#endif
1529 if (t >= work -> ntypes)
1530 {
1531 return (0);
1532 }
dd3b648e
RP
1533 while (--r >= 0)
1534 {
f9b5584c 1535 tem = work -> typevec[t];
8f793aa5 1536 if (need_comma && PRINT_ARG_TYPES)
f9b5584c
FF
1537 {
1538 string_append (declp, ", ");
1539 }
f536aa39 1540 if (!do_arg (&tem, &arg, work))
f9b5584c
FF
1541 {
1542 return (0);
1543 }
8f793aa5 1544 if (PRINT_ARG_TYPES)
f9b5584c
FF
1545 {
1546 string_appends (declp, &arg);
1547 }
dd3b648e
RP
1548 string_delete (&arg);
1549 need_comma = 1;
1550 }
1551 }
1552 else
1553 {
8f793aa5 1554 if (need_comma & PRINT_ARG_TYPES)
f9b5584c
FF
1555 {
1556 string_append (declp, ", ");
1557 }
f536aa39 1558 if (!do_arg (type, &arg, work))
f9b5584c
FF
1559 {
1560 return (0);
1561 }
8f793aa5 1562 if (PRINT_ARG_TYPES)
f9b5584c
FF
1563 {
1564 string_appends (declp, &arg);
1565 }
dd3b648e
RP
1566 string_delete (&arg);
1567 need_comma = 1;
1568 }
1569 }
1570
55b3ef9a 1571 if (**type == 'e')
dd3b648e 1572 {
f9b5584c 1573 (*type)++;
8f793aa5 1574 if (PRINT_ARG_TYPES)
dd3b648e
RP
1575 {
1576 if (need_comma)
f9b5584c
FF
1577 {
1578 string_append (declp, ",");
1579 }
1580 string_append (declp, "...");
dd3b648e
RP
1581 }
1582 }
1583
8f793aa5 1584 if (PRINT_ARG_TYPES)
f9b5584c
FF
1585 {
1586 string_append (declp, ")");
1587 }
1588 return (1);
dd3b648e
RP
1589}
1590
1591static void
f9b5584c
FF
1592demangle_function_name (declp, mangled, work, scan)
1593 string *declp;
1594 const char **mangled;
f536aa39 1595 struct work_stuff *work;
f9b5584c 1596 const char *scan;
dd3b648e 1597{
f9b5584c
FF
1598 int i;
1599 int len;
1600 string type;
1601 const char *tem;
1602
1603 string_appendn (declp, (*mangled), scan - (*mangled));
1604 string_need (declp, 1);
1605 *(declp -> p) = '\0';
1606
1607 /* Consume the function name, including the "__" separating the name
1608 from the signature. We are guaranteed that SCAN points to the
1609 separator. */
1610
1611 (*mangled) = scan + 2;
1612
1613#ifdef ARM_DEMANGLING
1614
1615 /* See if we have an ARM style constructor or destructor operator.
1616 If so, then just record it, clear the decl, and return.
1617 We can't build the actual constructor/destructor decl until later,
1618 when we recover the class name from the signature. */
1619
1620 if (strcmp (declp -> b, "__ct") == 0)
1621 {
1622 work -> constructor = 1;
1623 string_clear (declp);
1624 return;
1625 }
1626 else if (strcmp (declp -> b, "__dt") == 0)
1627 {
1628 work -> destructor = 1;
1629 string_clear (declp);
1630 return;
1631 }
1632
1633#endif
572acbbe 1634
f9b5584c
FF
1635 if (declp->p - declp->b >= 3
1636 && declp->b[0] == 'o'
1637 && declp->b[1] == 'p'
1638 && declp->b[2] == CPLUS_MARKER)
dd3b648e 1639 {
dd3b648e 1640 /* see if it's an assignment expression */
f9b5584c
FF
1641 if (declp->p - declp->b >= 10 /* op$assign_ */
1642 && memcmp (declp->b + 3, "assign_", 7) == 0)
dd3b648e 1643 {
f9b5584c 1644 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
dd3b648e 1645 {
f9b5584c 1646 len = declp->p - declp->b - 10;
dd3b648e 1647 if (strlen (optable[i].in) == len
f9b5584c 1648 && memcmp (optable[i].in, declp->b + 10, len) == 0)
dd3b648e 1649 {
f9b5584c
FF
1650 string_clear (declp);
1651 string_append (declp, "operator");
1652 string_append (declp, optable[i].out);
1653 string_append (declp, "=");
1654 break;
dd3b648e
RP
1655 }
1656 }
1657 }
1658 else
1659 {
f9b5584c 1660 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
dd3b648e 1661 {
f9b5584c 1662 int len = declp->p - declp->b - 3;
dd3b648e 1663 if (strlen (optable[i].in) == len
f9b5584c 1664 && memcmp (optable[i].in, declp->b + 3, len) == 0)
dd3b648e 1665 {
f9b5584c
FF
1666 string_clear (declp);
1667 string_append (declp, "operator");
1668 string_append (declp, optable[i].out);
1669 break;
dd3b648e
RP
1670 }
1671 }
1672 }
dd3b648e 1673 }
f9b5584c 1674 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type$", 5) == 0)
dd3b648e
RP
1675 {
1676 /* type conversion operator */
f9b5584c 1677 tem = declp->b + 5;
f536aa39 1678 if (do_type (&tem, &type, work))
dd3b648e 1679 {
f9b5584c
FF
1680 string_clear (declp);
1681 string_append (declp, "operator ");
1682 string_appends (declp, &type);
dd3b648e 1683 string_delete (&type);
dd3b648e
RP
1684 }
1685 }
f9b5584c 1686 else if (declp->b[2] == 'o' && declp->b[3] == 'p')
572acbbe 1687 {
f9b5584c 1688 /* ANSI. */
572acbbe 1689 /* type conversion operator. */
f9b5584c 1690 tem = declp->b + 4;
f536aa39 1691 if (do_type (&tem, &type, work))
572acbbe 1692 {
f9b5584c
FF
1693 string_clear (declp);
1694 string_append (declp, "operator ");
1695 string_appends (declp, &type);
572acbbe 1696 string_delete (&type);
572acbbe
MT
1697 }
1698 }
f9b5584c
FF
1699 else if (declp->b[0] == '_' && declp->b[1] == '_'
1700 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
1701 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
572acbbe 1702 {
f9b5584c 1703 if (declp->b[4] == '\0')
572acbbe
MT
1704 {
1705 /* Operator. */
f9b5584c 1706 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
572acbbe
MT
1707 {
1708 if (strlen (optable[i].in) == 2
f9b5584c 1709 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
572acbbe 1710 {
f9b5584c
FF
1711 string_clear (declp);
1712 string_append (declp, "operator");
1713 string_append (declp, optable[i].out);
1714 break;
572acbbe
MT
1715 }
1716 }
1717 }
1718 else
1719 {
f9b5584c 1720 if (declp->b[2] == 'a' && declp->b[5] == '\0')
572acbbe 1721 {
f9b5584c
FF
1722 /* Assignment. */
1723 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
572acbbe 1724 {
f9b5584c
FF
1725 if (strlen (optable[i].in) == 3
1726 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
1727 {
1728 string_clear (declp);
1729 string_append (declp, "operator");
1730 string_append (declp, optable[i].out);
1731 break;
1732 }
572acbbe
MT
1733 }
1734 }
1735 }
1736 }
dd3b648e
RP
1737}
1738
1739/* a mini string-handling package */
1740
1741static void
1742string_need (s, n)
1743 string *s;
1744 int n;
1745{
f9b5584c
FF
1746 int tem;
1747
dd3b648e
RP
1748 if (s->b == NULL)
1749 {
1750 if (n < 32)
f9b5584c
FF
1751 {
1752 n = 32;
1753 }
dd3b648e
RP
1754 s->p = s->b = (char *) xmalloc (n);
1755 s->e = s->b + n;
1756 }
1757 else if (s->e - s->p < n)
1758 {
f9b5584c 1759 tem = s->p - s->b;
dd3b648e
RP
1760 n += tem;
1761 n *= 2;
1762 s->b = (char *) xrealloc (s->b, n);
1763 s->p = s->b + tem;
1764 s->e = s->b + n;
1765 }
1766}
1767
1768static void
1769string_delete (s)
1770 string *s;
1771{
1772 if (s->b != NULL)
1773 {
1774 free (s->b);
1775 s->b = s->e = s->p = NULL;
1776 }
1777}
1778
1779static void
1780string_init (s)
1781 string *s;
1782{
1783 s->b = s->p = s->e = NULL;
1784}
1785
1786static void
1787string_clear (s)
1788 string *s;
1789{
1790 s->p = s->b;
1791}
1792
1793static int
1794string_empty (s)
1795 string *s;
1796{
f9b5584c 1797 return (s->b == s->p);
dd3b648e
RP
1798}
1799
1800static void
1801string_append (p, s)
1802 string *p;
1803 const char *s;
1804{
1805 int n;
1806 if (s == NULL || *s == '\0')
1807 return;
1808 n = strlen (s);
1809 string_need (p, n);
1810 memcpy (p->p, s, n);
1811 p->p += n;
1812}
1813
1814static void
1815string_appends (p, s)
1816 string *p, *s;
1817{
1818 int n;
f9b5584c
FF
1819
1820 if (s->b != s->p)
1821 {
1822 n = s->p - s->b;
1823 string_need (p, n);
1824 memcpy (p->p, s->b, n);
1825 p->p += n;
1826 }
dd3b648e
RP
1827}
1828
1829static void
1830string_appendn (p, s, n)
1831 string *p;
1832 const char *s;
1833 int n;
1834{
f9b5584c
FF
1835 if (n != 0)
1836 {
1837 string_need (p, n);
1838 memcpy (p->p, s, n);
1839 p->p += n;
1840 }
dd3b648e
RP
1841}
1842
1843static void
1844string_prepend (p, s)
1845 string *p;
1846 const char *s;
1847{
f9b5584c
FF
1848 if (s != NULL && *s != '\0')
1849 {
1850 string_prependn (p, s, strlen (s));
1851 }
dd3b648e
RP
1852}
1853
1854#if 0
1855static void
1856string_prepends (p, s)
1857 string *p, *s;
1858{
f9b5584c
FF
1859 if (s->b != s->p)
1860 {
1861 string_prependn (p, s->b, s->p - s->b);
1862 }
dd3b648e
RP
1863}
1864#endif
1865
1866static void
1867string_prependn (p, s, n)
1868 string *p;
1869 const char *s;
1870 int n;
1871{
1872 char *q;
1873
f9b5584c
FF
1874 if (n != 0)
1875 {
1876 string_need (p, n);
1877 for (q = p->p - 1; q >= p->b; q--)
1878 {
1879 q[n] = q[0];
1880 }
1881 memcpy (p->b, s, n);
1882 p->p += n;
1883 }
1884}
1885
1886/* To generate a standalone demangler program for testing purposes, just
1887 compile and link this file with -DMAIN. When run, it demangles each
1888 command line arg, or each stdin string, and prints the result on stdout. */
1889
1890#ifdef MAIN
1891
1892static void
1893demangle_it (mangled_name)
1894 char *mangled_name;
1895{
1896 char *result;
1897
1898 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
1899 if (result == NULL)
1900 {
1901 printf ("%s\n", mangled_name);
1902 }
1903 else
1904 {
1905 printf ("%s\n", result);
1906 free (result);
1907 }
1908}
1909
1910PTR
1911xmalloc (size)
1912 long size;
1913{
1914 PTR newmem;
1915
1916 if ((newmem = malloc ((int) size)) == NULL)
1917 {
1918 fprintf (stderr, "\nCan't allocate %u bytes\n", size);
1919 exit (1);
1920 }
1921 return (newmem);
1922}
1923
1924PTR
1925xrealloc (oldmem, size)
1926 PTR oldmem;
1927 long size;
1928{
1929 PTR newmem;
1930
1931 if ((newmem = realloc ((char *) oldmem, (int) size)) == NULL)
1932 {
1933 fprintf (stderr, "\nCan't reallocate %u bytes\n", size);
1934 exit (1);
1935 }
1936 return (newmem);
1937}
1938
1939main (argc, argv)
1940 int argc;
1941 char **argv;
1942{
1943 char mangled_name[128];
1944 char *result;
1945
1946 if (argc > 1)
1947 {
1948 argc--;
1949 argv++;
1950 while (argc-- > 0)
1951 {
1952 demangle_it (*argv);
1953 }
1954 }
1955 else
1956 {
1957 while (gets (mangled_name))
1958 {
1959 demangle_it (mangled_name);
1960 }
1961 }
dd3b648e 1962}
f9b5584c
FF
1963
1964#endif
This page took 0.13797 seconds and 4 git commands to generate.