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