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