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