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