]> gcc.gnu.org Git - gcc.git/blame - gcc/cplus-dem.c
(scc0_di, scc_di, seq, sne, sgt, sgtu, slt, sltu, sge, sgeu,
[gcc.git] / gcc / cplus-dem.c
CommitLineData
a3184468 1/* Demangler for GNU C++
9663100e 2 Copyright 1989, 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
a3184468
JM
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
940d9d63
RK
19not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
a3184468
JM
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
0f41302f 26 available memory. */
a3184468 27
5d644692
MS
28/* This file lives in both GCC and libiberty. When making changes, please
29 try not to break either. */
30
a3184468
JM
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));
a3184468 41
9663100e
ILT
42static const char *mystrstr PARAMS ((const char *, const char *));
43
44static const char *
f83d4617 45mystrstr (s1, s2)
9663100e 46 const char *s1, *s2;
c4b5dcfb 47{
9663100e 48 register const char *p = s1;
c4b5dcfb
RK
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}
c4b5dcfb 60
a3184468
JM
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
0f41302f 75 marker symbol (FIXME). */
a3184468
JM
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{
5d644692 89 cplus_markers[0] = ch;
a3184468
JM
90}
91
92/* Stuff that is shared between sub-routines.
0f41302f 93 Using a shared structure allows cplus_demangle to be reentrant. */
a3184468
JM
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 */
ddd5a7c1 187 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
a3184468 188 {"max", ">?", 0}, /* old */
ddd5a7c1 189 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
a3184468 190 {"min", "<?", 0}, /* old */
ddd5a7c1 191 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
a3184468
JM
192 {"nop", "", 0}, /* old (for operator=) */
193 {"rm", "->*", DMGL_ANSI} /* ansi */
194};
195
196
197typedef struct string /* Beware: these aren't required to be */
0f41302f 198{ /* '\0' terminated. */
a3184468
JM
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)) \
5d644692 206 string_prepend(str, " ");}
a3184468 207#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
5d644692 208 string_append(str, " ");}
a3184468
JM
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
9663100e
ILT
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
a3184468
JM
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
0f41302f 322 no consumption of input and a return of 0. */
a3184468
JM
323
324static int
325consume_count (type)
5d644692 326 const char **type;
a3184468 327{
5d644692 328 int count = 0;
a3184468 329
5d644692
MS
330 while (isdigit (**type))
331 {
332 count *= 10;
333 count += **type - '0';
334 (*type)++;
335 }
336 return (count);
a3184468
JM
337}
338
339int
340cplus_demangle_opname (opname, result, options)
47fd14f4 341 const char *opname;
a3184468
JM
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] == '_'
5d644692 356 && opname[2] == 'o' && opname[3] == 'p')
a3184468
JM
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 {
0f41302f 392 /* Assignment. */
a3184468
JM
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
5d644692
MS
408 && opname[0] == 'o'
409 && opname[1] == 'p'
410 && strchr (cplus_markers, opname[2]) != NULL)
a3184468
JM
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
47fd14f4 468const char *
a3184468 469cplus_mangle_opname (opname, options)
47fd14f4 470 const char *opname;
a3184468
JM
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)
47fd14f4 482 return optable[i].in;
a3184468
JM
483 }
484 return (0);
485}
486
a3184468
JM
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
0f41302f 539 example. */
a3184468
JM
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
0f41302f 576 /* Discard the remembered types, if any. */
a3184468
JM
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
0f41302f 585 terminated and return it. Otherwise, free the demangling decl. */
a3184468
JM
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
0f41302f 627 argument list. */
a3184468
JM
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 {
5d644692
MS
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;
a3184468 659
5d644692
MS
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;
a3184468 669
5d644692
MS
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;
a3184468 679
5d644692
MS
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;
a3184468 697
5d644692
MS
698 case 'F':
699 /* Function */
700 /* ARM style demangling includes a specific 'F' character after
a3184468
JM
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
0f41302f 703 with either style. */
a3184468 704
5d644692
MS
705 oldmangled = NULL;
706 func_done = 1;
707 (*mangled)++;
a3184468 708
5d644692
MS
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() */
a3184468 713
5d644692
MS
714 if (LUCID_DEMANGLING || ARM_DEMANGLING)
715 {
716 forget_types (work);
717 }
718 success = demangle_args (work, mangled, declp);
719 break;
a3184468 720
5d644692
MS
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, "::");
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;
a3184468 752
5d644692
MS
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;
a3184468 761
5d644692
MS
762 default:
763 if (AUTO_DEMANGLING || GNU_DEMANGLING)
a3184468 764 {
5d644692
MS
765 /* Assume we have stumbled onto the first outermost function
766 argument token, and start processing args. */
a3184468
JM
767 func_done = 1;
768 success = demangle_args (work, mangled, declp);
769 }
5d644692
MS
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;
a3184468 779 }
5d644692
MS
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 }
a3184468
JM
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',
0f41302f 800 which is in the current declp, so we leave it alone. */
a3184468
JM
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 string temp;
861
862 (*mangled)++;
863 start = *mangled;
864 /* get template name */
865 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
866 {
867 return (0);
868 }
869 if (trawname)
870 string_appendn (trawname, *mangled, r);
871 string_appendn (tname, *mangled, r);
872 *mangled += r;
873 string_append (tname, "<");
874 /* get size of template parameter list */
875 if (!get_count (mangled, &r))
876 {
877 return (0);
878 }
879 for (i = 0; i < r; i++)
880 {
881 if (need_comma)
882 {
883 string_append (tname, ", ");
884 }
885 /* Z for type parameters */
886 if (**mangled == 'Z')
887 {
888 (*mangled)++;
889 /* temp is initialized in do_type */
890 success = do_type (work, mangled, &temp);
891 if (success)
892 {
893 string_appends (tname, &temp);
894 }
895 string_delete(&temp);
896 if (!success)
897 {
898 break;
899 }
900 }
901 else
902 {
903 /* otherwise, value parameter */
904 old_p = *mangled;
905 is_pointer = 0;
906 is_real = 0;
907 is_integral = 0;
908 is_char = 0;
943a140b 909 is_bool = 0;
a3184468
JM
910 done = 0;
911 /* temp is initialized in do_type */
912 success = do_type (work, mangled, &temp);
5d644692
MS
913 /*
914 if (success)
a3184468 915 {
5d644692 916 string_appends (tname, &temp);
a3184468 917 }
5d644692 918 */
a3184468
JM
919 string_delete(&temp);
920 if (!success)
921 {
922 break;
923 }
5d644692
MS
924 /*
925 string_append (tname, "=");
926 */
a3184468
JM
927 while (*old_p && !done)
928 {
929 switch (*old_p)
930 {
5d644692
MS
931 case 'P':
932 case 'p':
933 case 'R':
934 done = is_pointer = 1;
935 break;
936 case 'C': /* const */
937 case 'S': /* explicitly signed [char] */
938 case 'U': /* unsigned */
939 case 'V': /* volatile */
940 case 'F': /* function */
941 case 'M': /* member function */
942 case 'O': /* ??? */
943 old_p++;
944 continue;
945 case 'Q': /* qualified name */
946 done = is_integral = 1;
947 break;
948 case 'T': /* remembered type */
949 abort ();
950 break;
951 case 'v': /* void */
952 abort ();
953 break;
954 case 'x': /* long long */
955 case 'l': /* long */
956 case 'i': /* int */
957 case 's': /* short */
958 case 'w': /* wchar_t */
959 done = is_integral = 1;
960 break;
961 case 'b': /* bool */
962 done = is_bool = 1;
963 break;
964 case 'c': /* char */
965 done = is_char = 1;
966 break;
967 case 'r': /* long double */
968 case 'd': /* double */
969 case 'f': /* float */
970 done = is_real = 1;
971 break;
972 default:
973 /* it's probably user defined type, let's assume
974 it's integral, it seems hard to figure out
975 what it really is */
976 done = is_integral = 1;
a3184468
JM
977 }
978 }
979 if (is_integral)
980 {
981 if (**mangled == 'm')
982 {
983 string_appendn (tname, "-", 1);
984 (*mangled)++;
985 }
986 while (isdigit (**mangled))
987 {
988 string_appendn (tname, *mangled, 1);
989 (*mangled)++;
990 }
991 }
992 else if (is_char)
993 {
5d644692
MS
994 char tmp[2];
995 int val;
a3184468
JM
996 if (**mangled == 'm')
997 {
998 string_appendn (tname, "-", 1);
999 (*mangled)++;
1000 }
1001 string_appendn (tname, "'", 1);
1002 val = consume_count(mangled);
1003 if (val == 0)
1004 {
1005 success = 0;
1006 break;
1007 }
1008 tmp[0] = (char)val;
1009 tmp[1] = '\0';
1010 string_appendn (tname, &tmp[0], 1);
1011 string_appendn (tname, "'", 1);
1012 }
1013 else if (is_bool)
1014 {
1015 int val = consume_count (mangled);
1016 if (val == 0)
1017 string_appendn (tname, "false", 5);
1018 else if (val == 1)
1019 string_appendn (tname, "true", 4);
1020 else
1021 success = 0;
1022 }
1023 else if (is_real)
1024 {
1025 if (**mangled == 'm')
1026 {
1027 string_appendn (tname, "-", 1);
1028 (*mangled)++;
1029 }
1030 while (isdigit (**mangled))
1031 {
1032 string_appendn (tname, *mangled, 1);
1033 (*mangled)++;
1034 }
1035 if (**mangled == '.') /* fraction */
1036 {
1037 string_appendn (tname, ".", 1);
1038 (*mangled)++;
1039 while (isdigit (**mangled))
1040 {
1041 string_appendn (tname, *mangled, 1);
1042 (*mangled)++;
1043 }
1044 }
1045 if (**mangled == 'e') /* exponent */
1046 {
1047 string_appendn (tname, "e", 1);
1048 (*mangled)++;
1049 while (isdigit (**mangled))
1050 {
1051 string_appendn (tname, *mangled, 1);
1052 (*mangled)++;
1053 }
1054 }
1055 }
1056 else if (is_pointer)
1057 {
c486ed79
JM
1058 symbol_len = consume_count (mangled);
1059 if (symbol_len == 0)
a3184468
JM
1060 {
1061 success = 0;
1062 break;
1063 }
943a140b
JM
1064 if (symbol_len == 0)
1065 string_appendn (tname, "0", 1);
1066 else
983edca4
JM
1067 {
1068 char *p = xmalloc (symbol_len + 1), *q;
1069 strncpy (p, *mangled, symbol_len);
ba9d9bfa 1070 p [symbol_len] = '\0';
983edca4
JM
1071 q = cplus_demangle (p, work->options);
1072 string_appendn (tname, "&", 1);
ba9d9bfa
JM
1073 if (q)
1074 {
1075 string_append (tname, q);
1076 free (q);
1077 }
1078 else
1079 string_append (tname, p);
983edca4 1080 free (p);
983edca4 1081 }
a3184468
JM
1082 *mangled += symbol_len;
1083 }
1084 }
1085 need_comma = 1;
1086 }
1087 if (tname->p[-1] == '>')
1088 string_append (tname, " ");
1089 string_append (tname, ">");
1090
5d644692
MS
1091 /*
1092 if (work -> static_type)
1093 {
1094 string_append (declp, *mangled + 1);
1095 *mangled += strlen (*mangled);
1096 success = 1;
a3184468 1097 }
5d644692
MS
1098 else
1099 {
1100 success = demangle_args (work, mangled, declp);
1101 }
1102 }
1103 */
a3184468
JM
1104 return (success);
1105}
1106
1107static int
1108arm_pt (work, mangled, n, anchor, args)
1109 struct work_stuff *work;
1110 const char *mangled;
1111 int n;
1112 const char **anchor, **args;
1113{
1114 /* ARM template? */
f83d4617 1115 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
a3184468 1116 {
5d644692
MS
1117 int len;
1118 *args = *anchor + 6;
1119 len = consume_count (args);
1120 if (*args + len == mangled + n && **args == '_')
1121 {
1122 ++*args;
1123 return 1;
1124 }
a3184468
JM
1125 }
1126 return 0;
1127}
1128
1129static void
1130demangle_arm_pt (work, mangled, n, declp)
1131 struct work_stuff *work;
1132 const char **mangled;
1133 int n;
1134 string *declp;
1135{
1136 const char *p;
1137 const char *args;
1138 const char *e = *mangled + n;
1139
1140 /* ARM template? */
1141 if (arm_pt (work, *mangled, n, &p, &args))
5d644692
MS
1142 {
1143 string arg;
1144 string_init (&arg);
1145 string_appendn (declp, *mangled, p - *mangled);
1146 string_append (declp, "<");
1147 /* should do error checking here */
1148 while (args < e) {
1149 string_clear (&arg);
1150 do_type (work, &args, &arg);
1151 string_appends (declp, &arg);
1152 string_append (declp, ",");
1153 }
1154 string_delete (&arg);
1155 --declp->p;
1156 string_append (declp, ">");
1157 }
a3184468 1158 else
5d644692
MS
1159 {
1160 string_appendn (declp, *mangled, n);
1161 }
a3184468
JM
1162 *mangled += n;
1163}
1164
1165static int
1166demangle_class_name (work, mangled, declp)
1167 struct work_stuff *work;
1168 const char **mangled;
1169 string *declp;
1170{
1171 int n;
1172 int success = 0;
1173
1174 n = consume_count (mangled);
1175 if (strlen (*mangled) >= n)
5d644692
MS
1176 {
1177 demangle_arm_pt (work, mangled, n, declp);
1178 success = 1;
1179 }
a3184468
JM
1180
1181 return (success);
1182}
1183
1184/*
1185
1186LOCAL FUNCTION
1187
1188 demangle_class -- demangle a mangled class sequence
1189
1190SYNOPSIS
1191
1192 static int
1193 demangle_class (struct work_stuff *work, const char **mangled,
1194 strint *declp)
1195
1196DESCRIPTION
1197
1198 DECLP points to the buffer into which demangling is being done.
1199
1200 *MANGLED points to the current token to be demangled. On input,
1201 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1202 On exit, it points to the next token after the mangled class on
1203 success, or the first unconsumed token on failure.
1204
abc95ed3 1205 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
a3184468
JM
1206 we are demangling a constructor or destructor. In this case
1207 we prepend "class::class" or "class::~class" to DECLP.
1208
1209 Otherwise, we prepend "class::" to the current DECLP.
1210
1211 Reset the constructor/destructor flags once they have been
1212 "consumed". This allows demangle_class to be called later during
1213 the same demangling, to do normal class demangling.
1214
1215 Returns 1 if demangling is successful, 0 otherwise.
1216
1217*/
1218
1219static int
1220demangle_class (work, mangled, declp)
1221 struct work_stuff *work;
1222 const char **mangled;
1223 string *declp;
1224{
1225 int success = 0;
1226 string class_name;
1227
1228 string_init (&class_name);
1229 if (demangle_class_name (work, mangled, &class_name))
1230 {
1231 if ((work->constructor & 1) || (work->destructor & 1))
1232 {
1233 string_prepends (declp, &class_name);
1234 if (work -> destructor & 1)
1235 {
1236 string_prepend (declp, "~");
1237 work -> destructor -= 1;
1238 }
1239 else
1240 {
1241 work -> constructor -= 1;
1242 }
1243 }
1244 string_prepend (declp, "::");
1245 string_prepends (declp, &class_name);
1246 success = 1;
1247 }
1248 string_delete (&class_name);
1249 return (success);
1250}
1251
1252/*
1253
1254LOCAL FUNCTION
1255
1256 demangle_prefix -- consume the mangled name prefix and find signature
1257
1258SYNOPSIS
1259
1260 static int
1261 demangle_prefix (struct work_stuff *work, const char **mangled,
1262 string *declp);
1263
1264DESCRIPTION
1265
1266 Consume and demangle the prefix of the mangled name.
1267
1268 DECLP points to the string buffer into which demangled output is
1269 placed. On entry, the buffer is empty. On exit it contains
1270 the root function name, the demangled operator name, or in some
1271 special cases either nothing or the completely demangled result.
1272
1273 MANGLED points to the current pointer into the mangled name. As each
1274 token of the mangled name is consumed, it is updated. Upon entry
1275 the current mangled name pointer points to the first character of
1276 the mangled name. Upon exit, it should point to the first character
1277 of the signature if demangling was successful, or to the first
1278 unconsumed character if demangling of the prefix was unsuccessful.
1279
1280 Returns 1 on success, 0 otherwise.
1281 */
1282
1283static int
1284demangle_prefix (work, mangled, declp)
1285 struct work_stuff *work;
1286 const char **mangled;
1287 string *declp;
1288{
1289 int success = 1;
1290 const char *scan;
1291 int i;
1292
1293 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1294 {
1295 char *marker = strchr (cplus_markers, (*mangled)[8]);
1296 if (marker != NULL && *marker == (*mangled)[10])
1297 {
1298 if ((*mangled)[9] == 'D')
1299 {
1300 /* it's a GNU global destructor to be executed at program exit */
1301 (*mangled) += 11;
1302 work->destructor = 2;
1303 if (gnu_special (work, mangled, declp))
1304 return success;
1305 }
1306 else if ((*mangled)[9] == 'I')
1307 {
1308 /* it's a GNU global constructor to be executed at program init */
1309 (*mangled) += 11;
1310 work->constructor = 2;
1311 if (gnu_special (work, mangled, declp))
1312 return success;
1313 }
1314 }
1315 }
1316 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1317 {
1318 /* it's a ARM global destructor to be executed at program exit */
1319 (*mangled) += 7;
1320 work->destructor = 2;
1321 }
1322 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1323 {
1324 /* it's a ARM global constructor to be executed at program initial */
1325 (*mangled) += 7;
1326 work->constructor = 2;
1327 }
1328
5d644692
MS
1329 /* This block of code is a reduction in strength time optimization
1330 of:
1331 scan = mystrstr (*mangled, "__"); */
a3184468
JM
1332
1333 {
1334 scan = *mangled;
1335
1336 do {
1337 scan = strchr (scan, '_');
1338 } while (scan != NULL && *++scan != '_');
1339
1340 if (scan != NULL) --scan;
1341 }
1342
1343 if (scan != NULL)
1344 {
1345 /* We found a sequence of two or more '_', ensure that we start at
0f41302f 1346 the last pair in the sequence. */
a3184468
JM
1347 i = strspn (scan, "_");
1348 if (i > 2)
1349 {
1350 scan += (i - 2);
1351 }
1352 }
1353
1354 if (scan == NULL)
1355 {
1356 success = 0;
1357 }
1358 else if (work -> static_type)
1359 {
1360 if (!isdigit (scan[0]) && (scan[0] != 't'))
1361 {
1362 success = 0;
1363 }
1364 }
e3da301d
MS
1365 else if ((scan == *mangled)
1366 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
a3184468
JM
1367 {
1368 /* The ARM says nothing about the mangling of local variables.
1369 But cfront mangles local variables by prepending __<nesting_level>
1370 to them. As an extension to ARM demangling we handle this case. */
1371 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1372 {
1373 *mangled = scan + 2;
1374 consume_count (mangled);
1375 string_append (declp, *mangled);
1376 *mangled += strlen (*mangled);
1377 success = 1;
1378 }
1379 else
1380 {
1381 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1382 names like __Q2_3foo3bar for nested type names. So don't accept
1383 this style of constructor for cfront demangling. */
1384 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1385 work -> constructor += 1;
1386 *mangled = scan + 2;
1387 }
1388 }
1389 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1390 {
1391 /* Mangled name starts with "__". Skip over any leading '_' characters,
1392 then find the next "__" that separates the prefix from the signature.
1393 */
1394 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1395 || (arm_special (work, mangled, declp) == 0))
1396 {
1397 while (*scan == '_')
1398 {
1399 scan++;
1400 }
f83d4617 1401 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
a3184468
JM
1402 {
1403 /* No separator (I.E. "__not_mangled"), or empty signature
1404 (I.E. "__not_mangled_either__") */
1405 success = 0;
1406 }
1407 else
1408 {
1409 demangle_function_name (work, mangled, declp, scan);
1410 }
1411 }
1412 }
1413 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1414 {
0f41302f 1415 /* Cfront-style parameterized type. Handled later as a signature. */
a3184468
JM
1416 success = 1;
1417
1418 /* ARM template? */
1419 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1420 }
1421 else if (*(scan + 2) != '\0')
1422 {
1423 /* Mangled name does not start with "__" but does have one somewhere
1424 in there with non empty stuff after it. Looks like a global
0f41302f 1425 function name. */
a3184468
JM
1426 demangle_function_name (work, mangled, declp, scan);
1427 }
1428 else
1429 {
1430 /* Doesn't look like a mangled name */
1431 success = 0;
1432 }
1433
1434 if (!success && (work->constructor == 2 || work->destructor == 2))
1435 {
1436 string_append (declp, *mangled);
1437 *mangled += strlen (*mangled);
1438 success = 1;
1439 }
1440 return (success);
1441}
1442
1443/*
1444
1445LOCAL FUNCTION
1446
1447 gnu_special -- special handling of gnu mangled strings
1448
1449SYNOPSIS
1450
1451 static int
1452 gnu_special (struct work_stuff *work, const char **mangled,
1453 string *declp);
1454
1455
1456DESCRIPTION
1457
1458 Process some special GNU style mangling forms that don't fit
1459 the normal pattern. For example:
1460
1461 _$_3foo (destructor for class foo)
1462 _vt$foo (foo virtual table)
1463 _vt$foo$bar (foo::bar virtual table)
1464 __vt_foo (foo virtual table, new style with thunks)
1465 _3foo$varname (static data member)
1466 _Q22rs2tu$vw (static data member)
1467 __t6vector1Zii (constructor with template)
1468 __thunk_4__$_7ostream (virtual function thunk)
1469 */
1470
1471static int
1472gnu_special (work, mangled, declp)
1473 struct work_stuff *work;
1474 const char **mangled;
1475 string *declp;
1476{
1477 int n;
1478 int success = 1;
1479 const char *p;
1480
1481 if ((*mangled)[0] == '_'
1482 && strchr (cplus_markers, (*mangled)[1]) != NULL
1483 && (*mangled)[2] == '_')
1484 {
1485 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1486 (*mangled) += 3;
1487 work -> destructor += 1;
1488 }
1489 else if ((*mangled)[0] == '_'
1490 && (((*mangled)[1] == '_'
1491 && (*mangled)[2] == 'v'
1492 && (*mangled)[3] == 't'
1493 && (*mangled)[4] == '_')
5d644692
MS
1494 || ((*mangled)[1] == 'v'
1495 && (*mangled)[2] == 't'
1496 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
a3184468
JM
1497 {
1498 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1499 and create the decl. Note that we consume the entire mangled
1500 input string, which means that demangle_signature has no work
0f41302f 1501 to do. */
a3184468
JM
1502 if ((*mangled)[2] == 'v')
1503 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1504 else
1505 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1506 while (**mangled != '\0')
1507 {
1508 p = strpbrk (*mangled, cplus_markers);
1509 switch (**mangled)
1510 {
1511 case 'Q':
1512 success = demangle_qualified (work, mangled, declp, 0, 1);
1513 break;
1514 case 't':
1515 success = demangle_template (work, mangled, declp, 0);
1516 break;
1517 default:
1518 if (isdigit(*mangled[0]))
1519 {
1520 n = consume_count(mangled);
1521 }
1522 else
1523 {
1524 n = strcspn (*mangled, cplus_markers);
1525 }
1526 string_appendn (declp, *mangled, n);
1527 (*mangled) += n;
1528 }
1529
1530 if (success && ((p == NULL) || (p == *mangled)))
1531 {
1532 if (p != NULL)
1533 {
1534 string_append (declp, "::");
1535 (*mangled)++;
1536 }
1537 }
1538 else
1539 {
1540 success = 0;
1541 break;
1542 }
1543 }
1544 if (success)
1545 string_append (declp, " virtual table");
1546 }
1547 else if ((*mangled)[0] == '_'
1548 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1549 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1550 {
1551 /* static data member, "_3foo$varname" for example */
1552 (*mangled)++;
1553 switch (**mangled)
1554 {
5d644692
MS
1555 case 'Q':
1556 success = demangle_qualified (work, mangled, declp, 0, 1);
1557 break;
1558 case 't':
1559 success = demangle_template (work, mangled, declp, 0);
1560 break;
1561 default:
1562 n = consume_count (mangled);
1563 string_appendn (declp, *mangled, n);
1564 (*mangled) += n;
a3184468
JM
1565 }
1566 if (success && (p == *mangled))
1567 {
1568 /* Consumed everything up to the cplus_marker, append the
0f41302f 1569 variable name. */
a3184468
JM
1570 (*mangled)++;
1571 string_append (declp, "::");
1572 n = strlen (*mangled);
1573 string_appendn (declp, *mangled, n);
1574 (*mangled) += n;
1575 }
1576 else
1577 {
1578 success = 0;
1579 }
1580 }
1581 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1582 {
1583 int delta = ((*mangled) += 8, consume_count (mangled));
1584 char *method = cplus_demangle (++*mangled, work->options);
1585 if (method)
1586 {
1587 char buf[50];
1588 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1589 string_append (declp, buf);
1590 string_append (declp, method);
1591 free (method);
1592 n = strlen (*mangled);
1593 (*mangled) += n;
1594 }
1595 else
1596 {
1597 success = 0;
1598 }
1599 }
c486ed79
JM
1600 else if (strncmp (*mangled, "__t", 3) == 0
1601 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1602 {
1603 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1604 (*mangled) += 4;
1605 switch (**mangled)
1606 {
5d644692
MS
1607 case 'Q':
1608 success = demangle_qualified (work, mangled, declp, 0, 1);
1609 break;
1610 case 't':
1611 success = demangle_template (work, mangled, declp, 0);
1612 break;
1613 default:
e9b1360b
BK
1614 success = demangle_fund_type (work, mangled, declp);
1615 break;
c486ed79
JM
1616 }
1617 if (success && **mangled != '\0')
1618 success = 0;
1619 if (success)
1620 string_append (declp, p);
1621 }
a3184468
JM
1622 else
1623 {
1624 success = 0;
1625 }
1626 return (success);
1627}
1628
1629/*
1630
1631LOCAL FUNCTION
1632
1633 arm_special -- special handling of ARM/lucid mangled strings
1634
1635SYNOPSIS
1636
1637 static int
1638 arm_special (struct work_stuff *work, const char **mangled,
1639 string *declp);
1640
1641
1642DESCRIPTION
1643
1644 Process some special ARM style mangling forms that don't fit
1645 the normal pattern. For example:
1646
1647 __vtbl__3foo (foo virtual table)
1648 __vtbl__3foo__3bar (bar::foo virtual table)
1649
1650 */
1651
1652static int
1653arm_special (work, mangled, declp)
1654 struct work_stuff *work;
1655 const char **mangled;
1656 string *declp;
1657{
1658 int n;
1659 int success = 1;
1660 const char *scan;
1661
1662 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1663 {
1664 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1665 and create the decl. Note that we consume the entire mangled
1666 input string, which means that demangle_signature has no work
0f41302f 1667 to do. */
a3184468
JM
1668 scan = *mangled + ARM_VTABLE_STRLEN;
1669 while (*scan != '\0') /* first check it can be demangled */
1670 {
1671 n = consume_count (&scan);
1672 if (n==0)
1673 {
1674 return (0); /* no good */
1675 }
1676 scan += n;
1677 if (scan[0] == '_' && scan[1] == '_')
1678 {
1679 scan += 2;
1680 }
1681 }
1682 (*mangled) += ARM_VTABLE_STRLEN;
1683 while (**mangled != '\0')
1684 {
1685 n = consume_count (mangled);
1686 string_prependn (declp, *mangled, n);
1687 (*mangled) += n;
1688 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1689 {
1690 string_prepend (declp, "::");
1691 (*mangled) += 2;
1692 }
1693 }
1694 string_append (declp, " virtual table");
1695 }
1696 else
1697 {
1698 success = 0;
1699 }
1700 return (success);
1701}
1702
1703/*
1704
1705LOCAL FUNCTION
1706
1707 demangle_qualified -- demangle 'Q' qualified name strings
1708
1709SYNOPSIS
1710
1711 static int
1712 demangle_qualified (struct work_stuff *, const char *mangled,
1713 string *result, int isfuncname, int append);
1714
1715DESCRIPTION
1716
1717 Demangle a qualified name, such as "Q25Outer5Inner" which is
1718 the mangled form of "Outer::Inner". The demangled output is
1719 prepended or appended to the result string according to the
1720 state of the append flag.
1721
1722 If isfuncname is nonzero, then the qualified name we are building
1723 is going to be used as a member function name, so if it is a
1724 constructor or destructor function, append an appropriate
1725 constructor or destructor name. I.E. for the above example,
1726 the result for use as a constructor is "Outer::Inner::Inner"
1727 and the result for use as a destructor is "Outer::Inner::~Inner".
1728
1729BUGS
1730
1731 Numeric conversion is ASCII dependent (FIXME).
1732
1733 */
1734
1735static int
1736demangle_qualified (work, mangled, result, isfuncname, append)
1737 struct work_stuff *work;
1738 const char **mangled;
1739 string *result;
1740 int isfuncname;
1741 int append;
1742{
1743 int qualifiers;
1744 int namelength;
1745 int success = 1;
1746 const char *p;
1747 char num[2];
1748 string temp;
1749
1750 string_init (&temp);
1751 switch ((*mangled)[1])
1752 {
1753 case '_':
1754 /* GNU mangled name with more than 9 classes. The count is preceded
1755 by an underscore (to distinguish it from the <= 9 case) and followed
1756 by an underscore. */
1757 p = *mangled + 2;
1758 qualifiers = atoi (p);
1759 if (!isdigit (*p) || *p == '0')
1760 success = 0;
1761
1762 /* Skip the digits. */
1763 while (isdigit (*p))
1764 ++p;
1765
1766 if (*p != '_')
1767 success = 0;
1768
1769 *mangled = p + 1;
1770 break;
1771
1772 case '1':
1773 case '2':
1774 case '3':
1775 case '4':
1776 case '5':
1777 case '6':
1778 case '7':
1779 case '8':
1780 case '9':
1781 /* The count is in a single digit. */
1782 num[0] = (*mangled)[1];
1783 num[1] = '\0';
1784 qualifiers = atoi (num);
1785
1786 /* If there is an underscore after the digit, skip it. This is
1787 said to be for ARM-qualified names, but the ARM makes no
1788 mention of such an underscore. Perhaps cfront uses one. */
1789 if ((*mangled)[2] == '_')
1790 {
1791 (*mangled)++;
1792 }
1793 (*mangled) += 2;
1794 break;
1795
1796 case '0':
1797 default:
1798 success = 0;
1799 }
1800
1801 if (!success)
1802 return success;
1803
1804 /* Pick off the names and collect them in the temp buffer in the order
0f41302f 1805 in which they are found, separated by '::'. */
a3184468
JM
1806
1807 while (qualifiers-- > 0)
1808 {
1809 if (*mangled[0] == '_')
1810 *mangled = *mangled + 1;
1811 if (*mangled[0] == 't')
1812 {
1813 success = demangle_template(work, mangled, &temp, 0);
1814 if (!success) break;
1815 }
1816 else
1817 {
1818 namelength = consume_count (mangled);
1819 if (strlen (*mangled) < namelength)
1820 {
5d644692
MS
1821 /* Simple sanity check failed */
1822 success = 0;
1823 break;
a3184468
JM
1824 }
1825 string_appendn (&temp, *mangled, namelength);
1826 *mangled += namelength;
1827 }
1828 if (qualifiers > 0)
1829 {
1830 string_appendn (&temp, "::", 2);
1831 }
1832 }
1833
1834 /* If we are using the result as a function name, we need to append
1835 the appropriate '::' separated constructor or destructor name.
1836 We do this here because this is the most convenient place, where
0f41302f 1837 we already have a pointer to the name and the length of the name. */
a3184468
JM
1838
1839 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1840 {
1841 string_appendn (&temp, "::", 2);
1842 if (work -> destructor & 1)
1843 {
1844 string_append (&temp, "~");
1845 }
1846 string_appendn (&temp, (*mangled) - namelength, namelength);
1847 }
1848
1849 /* Now either prepend the temp buffer to the result, or append it,
0f41302f 1850 depending upon the state of the append flag. */
a3184468
JM
1851
1852 if (append)
1853 {
1854 string_appends (result, &temp);
1855 }
1856 else
1857 {
1858 if (!STRING_EMPTY (result))
1859 {
1860 string_appendn (&temp, "::", 2);
1861 }
1862 string_prepends (result, &temp);
1863 }
1864
1865 string_delete (&temp);
1866 return (success);
1867}
1868
1869/*
1870
1871LOCAL FUNCTION
1872
1873 get_count -- convert an ascii count to integer, consuming tokens
1874
1875SYNOPSIS
1876
1877 static int
1878 get_count (const char **type, int *count)
1879
1880DESCRIPTION
1881
1882 Return 0 if no conversion is performed, 1 if a string is converted.
1883*/
1884
1885static int
1886get_count (type, count)
1887 const char **type;
1888 int *count;
1889{
1890 const char *p;
1891 int n;
1892
1893 if (!isdigit (**type))
1894 {
1895 return (0);
1896 }
1897 else
1898 {
1899 *count = **type - '0';
1900 (*type)++;
1901 if (isdigit (**type))
1902 {
1903 p = *type;
1904 n = *count;
1905 do
1906 {
1907 n *= 10;
1908 n += *p - '0';
1909 p++;
1910 }
1911 while (isdigit (*p));
1912 if (*p == '_')
1913 {
1914 *type = p + 1;
1915 *count = n;
1916 }
1917 }
1918 }
1919 return (1);
1920}
1921
1922/* result will be initialised here; it will be freed on failure */
1923
1924static int
1925do_type (work, mangled, result)
1926 struct work_stuff *work;
1927 const char **mangled;
1928 string *result;
1929{
1930 int n;
1931 int done;
1932 int success;
1933 string decl;
1934 const char *remembered_type;
1935 int constp;
1936 int volatilep;
1937
1938 string_init (&decl);
1939 string_init (result);
1940
1941 done = 0;
1942 success = 1;
1943 while (success && !done)
1944 {
1945 int member;
1946 switch (**mangled)
1947 {
1948
5d644692 1949 /* A pointer type */
a3184468
JM
1950 case 'P':
1951 case 'p':
1952 (*mangled)++;
1953 string_prepend (&decl, "*");
1954 break;
1955
5d644692 1956 /* A reference type */
a3184468
JM
1957 case 'R':
1958 (*mangled)++;
1959 string_prepend (&decl, "&");
1960 break;
1961
5d644692 1962 /* An array */
a3184468
JM
1963 case 'A':
1964 {
1965 const char *p = ++(*mangled);
1966
1967 string_prepend (&decl, "(");
1968 string_append (&decl, ")[");
1969 /* Copy anything up until the next underscore (the size of the
1970 array). */
1971 while (**mangled && **mangled != '_')
1972 ++(*mangled);
1973 if (**mangled == '_')
1974 {
1975 string_appendn (&decl, p, *mangled - p);
1976 string_append (&decl, "]");
1977 *mangled += 1;
1978 }
1979 else
1980 success = 0;
1981 break;
1982 }
1983
1984 /* A back reference to a previously seen type */
1985 case 'T':
1986 (*mangled)++;
1987 if (!get_count (mangled, &n) || n >= work -> ntypes)
1988 {
1989 success = 0;
1990 }
1991 else
1992 {
1993 remembered_type = work -> typevec[n];
1994 mangled = &remembered_type;
1995 }
1996 break;
1997
5d644692 1998 /* A function */
a3184468
JM
1999 case 'F':
2000 (*mangled)++;
2001 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2002 {
2003 string_prepend (&decl, "(");
2004 string_append (&decl, ")");
2005 }
2006 /* After picking off the function args, we expect to either find the
2007 function return type (preceded by an '_') or the end of the
0f41302f 2008 string. */
a3184468
JM
2009 if (!demangle_args (work, mangled, &decl)
2010 || (**mangled != '_' && **mangled != '\0'))
2011 {
2012 success = 0;
2013 }
2014 if (success && (**mangled == '_'))
2015 {
2016 (*mangled)++;
2017 }
2018 break;
2019
2020 case 'M':
2021 case 'O':
2022 {
2023 constp = 0;
2024 volatilep = 0;
2025
2026 member = **mangled == 'M';
2027 (*mangled)++;
5d644692 2028 if (!isdigit (**mangled) && **mangled != 't')
a3184468
JM
2029 {
2030 success = 0;
2031 break;
2032 }
5d644692 2033
a3184468
JM
2034 string_append (&decl, ")");
2035 string_prepend (&decl, "::");
5d644692
MS
2036 if (isdigit (**mangled))
2037 {
2038 n = consume_count (mangled);
2039 if (strlen (*mangled) < n)
2040 {
2041 success = 0;
2042 break;
2043 }
2044 string_prependn (&decl, *mangled, n);
2045 *mangled += n;
2046 }
2047 else
2048 {
2049 string temp;
2050 string_init (&temp);
2051 success = demangle_template (work, mangled, &temp, NULL);
2052 if (success)
2053 {
2054 string_prependn (&decl, temp.b, temp.p - temp.b);
2055 string_clear (&temp);
2056 }
2057 else
2058 break;
2059 }
a3184468 2060 string_prepend (&decl, "(");
a3184468
JM
2061 if (member)
2062 {
2063 if (**mangled == 'C')
2064 {
2065 (*mangled)++;
2066 constp = 1;
2067 }
2068 if (**mangled == 'V')
2069 {
2070 (*mangled)++;
2071 volatilep = 1;
2072 }
2073 if (*(*mangled)++ != 'F')
2074 {
2075 success = 0;
2076 break;
2077 }
2078 }
2079 if ((member && !demangle_args (work, mangled, &decl))
2080 || **mangled != '_')
2081 {
2082 success = 0;
2083 break;
2084 }
2085 (*mangled)++;
2086 if (! PRINT_ANSI_QUALIFIERS)
2087 {
2088 break;
2089 }
2090 if (constp)
2091 {
2092 APPEND_BLANK (&decl);
2093 string_append (&decl, "const");
2094 }
2095 if (volatilep)
2096 {
2097 APPEND_BLANK (&decl);
2098 string_append (&decl, "volatile");
2099 }
2100 break;
2101 }
2102 case 'G':
5d644692
MS
2103 (*mangled)++;
2104 break;
a3184468
JM
2105
2106 case 'C':
2107 (*mangled)++;
5d644692
MS
2108 /*
2109 if ((*mangled)[1] == 'P')
a3184468 2110 {
5d644692
MS
2111 */
2112 if (PRINT_ANSI_QUALIFIERS)
2113 {
2114 if (!STRING_EMPTY (&decl))
a3184468 2115 {
5d644692 2116 string_prepend (&decl, " ");
a3184468 2117 }
5d644692 2118 string_prepend (&decl, "const");
a3184468 2119 }
5d644692
MS
2120 break;
2121 /*
2122 }
2123 */
a3184468
JM
2124
2125 /* fall through */
2126 default:
2127 done = 1;
2128 break;
2129 }
2130 }
2131
2132 switch (**mangled)
2133 {
0f41302f 2134 /* A qualified name, such as "Outer::Inner". */
5d644692
MS
2135 case 'Q':
2136 success = demangle_qualified (work, mangled, result, 0, 1);
2137 break;
a3184468 2138
5d644692
MS
2139 default:
2140 success = demangle_fund_type (work, mangled, result);
2141 break;
a3184468
JM
2142 }
2143
2144 if (success)
2145 {
2146 if (!STRING_EMPTY (&decl))
2147 {
2148 string_append (result, " ");
2149 string_appends (result, &decl);
2150 }
2151 }
2152 else
2153 {
2154 string_delete (result);
2155 }
2156 string_delete (&decl);
2157 return (success);
2158}
2159
2160/* Given a pointer to a type string that represents a fundamental type
2161 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2162 string in which the demangled output is being built in RESULT, and
2163 the WORK structure, decode the types and add them to the result.
2164
2165 For example:
2166
2167 "Ci" => "const int"
2168 "Sl" => "signed long"
2169 "CUs" => "const unsigned short"
2170
2171 */
2172
2173static int
2174demangle_fund_type (work, mangled, result)
2175 struct work_stuff *work;
2176 const char **mangled;
2177 string *result;
2178{
2179 int done = 0;
2180 int success = 1;
2181
0f41302f 2182 /* First pick off any type qualifiers. There can be more than one. */
a3184468
JM
2183
2184 while (!done)
2185 {
2186 switch (**mangled)
2187 {
5d644692
MS
2188 case 'C':
2189 (*mangled)++;
2190 if (PRINT_ANSI_QUALIFIERS)
2191 {
2192 APPEND_BLANK (result);
2193 string_append (result, "const");
2194 }
2195 break;
2196 case 'U':
2197 (*mangled)++;
2198 APPEND_BLANK (result);
2199 string_append (result, "unsigned");
2200 break;
2201 case 'S': /* signed char only */
2202 (*mangled)++;
2203 APPEND_BLANK (result);
2204 string_append (result, "signed");
2205 break;
2206 case 'V':
2207 (*mangled)++;
2208 if (PRINT_ANSI_QUALIFIERS)
2209 {
2210 APPEND_BLANK (result);
2211 string_append (result, "volatile");
2212 }
2213 break;
2214 default:
2215 done = 1;
2216 break;
a3184468
JM
2217 }
2218 }
2219
0f41302f 2220 /* Now pick off the fundamental type. There can be only one. */
a3184468
JM
2221
2222 switch (**mangled)
2223 {
5d644692
MS
2224 case '\0':
2225 case '_':
2226 break;
2227 case 'v':
2228 (*mangled)++;
2229 APPEND_BLANK (result);
2230 string_append (result, "void");
2231 break;
2232 case 'x':
2233 (*mangled)++;
2234 APPEND_BLANK (result);
2235 string_append (result, "long long");
2236 break;
2237 case 'l':
2238 (*mangled)++;
2239 APPEND_BLANK (result);
2240 string_append (result, "long");
2241 break;
2242 case 'i':
2243 (*mangled)++;
2244 APPEND_BLANK (result);
2245 string_append (result, "int");
2246 break;
2247 case 's':
2248 (*mangled)++;
2249 APPEND_BLANK (result);
2250 string_append (result, "short");
2251 break;
2252 case 'b':
2253 (*mangled)++;
2254 APPEND_BLANK (result);
2255 string_append (result, "bool");
2256 break;
2257 case 'c':
2258 (*mangled)++;
2259 APPEND_BLANK (result);
2260 string_append (result, "char");
2261 break;
2262 case 'w':
2263 (*mangled)++;
2264 APPEND_BLANK (result);
2265 string_append (result, "wchar_t");
2266 break;
2267 case 'r':
2268 (*mangled)++;
2269 APPEND_BLANK (result);
2270 string_append (result, "long double");
2271 break;
2272 case 'd':
2273 (*mangled)++;
2274 APPEND_BLANK (result);
2275 string_append (result, "double");
2276 break;
2277 case 'f':
2278 (*mangled)++;
2279 APPEND_BLANK (result);
2280 string_append (result, "float");
2281 break;
2282 case 'G':
2283 (*mangled)++;
2284 if (!isdigit (**mangled))
2285 {
a3184468 2286 success = 0;
5d644692 2287 break;
a3184468 2288 }
5d644692
MS
2289 /* fall through */
2290 /* An explicit type, such as "6mytype" or "7integer" */
2291 case '0':
2292 case '1':
2293 case '2':
2294 case '3':
2295 case '4':
2296 case '5':
2297 case '6':
2298 case '7':
2299 case '8':
2300 case '9':
2301 APPEND_BLANK (result);
2302 if (!demangle_class_name (work, mangled, result)) {
2303 --result->p;
a3184468 2304 success = 0;
a3184468 2305 }
5d644692
MS
2306 break;
2307 case 't':
2308 success = demangle_template(work,mangled, result, 0);
2309 break;
2310 default:
2311 success = 0;
2312 break;
2313 }
a3184468
JM
2314
2315 return (success);
2316}
2317
2318/* `result' will be initialized in do_type; it will be freed on failure */
2319
2320static int
2321do_arg (work, mangled, result)
2322 struct work_stuff *work;
2323 const char **mangled;
2324 string *result;
2325{
2326 const char *start = *mangled;
2327
2328 if (!do_type (work, mangled, result))
2329 {
2330 return (0);
2331 }
2332 else
2333 {
2334 remember_type (work, start, *mangled - start);
2335 return (1);
2336 }
2337}
2338
2339static void
2340remember_type (work, start, len)
2341 struct work_stuff *work;
2342 const char *start;
2343 int len;
2344{
2345 char *tem;
2346
2347 if (work -> ntypes >= work -> typevec_size)
2348 {
2349 if (work -> typevec_size == 0)
2350 {
2351 work -> typevec_size = 3;
e3da301d
MS
2352 work -> typevec
2353 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
a3184468
JM
2354 }
2355 else
2356 {
2357 work -> typevec_size *= 2;
e3da301d
MS
2358 work -> typevec
2359 = (char **) xrealloc ((char *)work -> typevec,
2360 sizeof (char *) * work -> typevec_size);
a3184468
JM
2361 }
2362 }
2363 tem = xmalloc (len + 1);
2364 memcpy (tem, start, len);
2365 tem[len] = '\0';
2366 work -> typevec[work -> ntypes++] = tem;
2367}
2368
0f41302f 2369/* Forget the remembered types, but not the type vector itself. */
a3184468
JM
2370
2371static void
2372forget_types (work)
2373 struct work_stuff *work;
2374{
2375 int i;
2376
2377 while (work -> ntypes > 0)
2378 {
2379 i = --(work -> ntypes);
2380 if (work -> typevec[i] != NULL)
2381 {
2382 free (work -> typevec[i]);
2383 work -> typevec[i] = NULL;
2384 }
2385 }
2386}
2387
2388/* Process the argument list part of the signature, after any class spec
2389 has been consumed, as well as the first 'F' character (if any). For
2390 example:
2391
2392 "__als__3fooRT0" => process "RT0"
2393 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2394
2395 DECLP must be already initialised, usually non-empty. It won't be freed
2396 on failure.
2397
2398 Note that g++ differs significantly from ARM and lucid style mangling
2399 with regards to references to previously seen types. For example, given
2400 the source fragment:
2401
2402 class foo {
2403 public:
2404 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2405 };
2406
2407 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2408 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2409
2410 g++ produces the names:
2411
2412 __3fooiRT0iT2iT2
2413 foo__FiR3fooiT1iT1
2414
2415 while lcc (and presumably other ARM style compilers as well) produces:
2416
2417 foo__FiR3fooT1T2T1T2
2418 __ct__3fooFiR3fooT1T2T1T2
2419
2420 Note that g++ bases it's type numbers starting at zero and counts all
2421 previously seen types, while lucid/ARM bases it's type numbers starting
2422 at one and only considers types after it has seen the 'F' character
2423 indicating the start of the function args. For lucid/ARM style, we
2424 account for this difference by discarding any previously seen types when
2425 we see the 'F' character, and subtracting one from the type number
2426 reference.
2427
2428 */
2429
2430static int
2431demangle_args (work, mangled, declp)
2432 struct work_stuff *work;
2433 const char **mangled;
2434 string *declp;
2435{
2436 string arg;
2437 int need_comma = 0;
2438 int r;
2439 int t;
2440 const char *tem;
2441 char temptype;
2442
2443 if (PRINT_ARG_TYPES)
2444 {
2445 string_append (declp, "(");
2446 if (**mangled == '\0')
2447 {
2448 string_append (declp, "void");
2449 }
2450 }
2451
2452 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2453 {
2454 if ((**mangled == 'N') || (**mangled == 'T'))
2455 {
2456 temptype = *(*mangled)++;
2457
2458 if (temptype == 'N')
2459 {
2460 if (!get_count (mangled, &r))
2461 {
2462 return (0);
2463 }
2464 }
2465 else
2466 {
2467 r = 1;
2468 }
2469 if (ARM_DEMANGLING && work -> ntypes >= 10)
2470 {
2471 /* If we have 10 or more types we might have more than a 1 digit
2472 index so we'll have to consume the whole count here. This
ddd5a7c1 2473 will lose if the next thing is a type name preceded by a
a3184468
JM
2474 count but it's impossible to demangle that case properly
2475 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
a3184468
JM
2476 Pc, ...)" or "(..., type12, char *, ...)" */
2477 if ((t = consume_count(mangled)) == 0)
2478 {
2479 return (0);
2480 }
2481 }
2482 else
2483 {
2484 if (!get_count (mangled, &t))
2485 {
2486 return (0);
2487 }
2488 }
2489 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2490 {
2491 t--;
2492 }
2493 /* Validate the type index. Protect against illegal indices from
0f41302f 2494 malformed type strings. */
a3184468
JM
2495 if ((t < 0) || (t >= work -> ntypes))
2496 {
2497 return (0);
2498 }
2499 while (--r >= 0)
2500 {
2501 tem = work -> typevec[t];
2502 if (need_comma && PRINT_ARG_TYPES)
2503 {
2504 string_append (declp, ", ");
2505 }
2506 if (!do_arg (work, &tem, &arg))
2507 {
2508 return (0);
2509 }
2510 if (PRINT_ARG_TYPES)
2511 {
2512 string_appends (declp, &arg);
2513 }
2514 string_delete (&arg);
2515 need_comma = 1;
2516 }
2517 }
2518 else
2519 {
2520 if (need_comma & PRINT_ARG_TYPES)
2521 {
2522 string_append (declp, ", ");
2523 }
2524 if (!do_arg (work, mangled, &arg))
2525 {
2526 return (0);
2527 }
2528 if (PRINT_ARG_TYPES)
2529 {
2530 string_appends (declp, &arg);
2531 }
2532 string_delete (&arg);
2533 need_comma = 1;
2534 }
2535 }
2536
2537 if (**mangled == 'e')
2538 {
2539 (*mangled)++;
2540 if (PRINT_ARG_TYPES)
2541 {
2542 if (need_comma)
2543 {
2544 string_append (declp, ",");
2545 }
2546 string_append (declp, "...");
2547 }
2548 }
2549
2550 if (PRINT_ARG_TYPES)
2551 {
2552 string_append (declp, ")");
2553 }
2554 return (1);
2555}
2556
2557static void
2558demangle_function_name (work, mangled, declp, scan)
2559 struct work_stuff *work;
2560 const char **mangled;
2561 string *declp;
2562 const char *scan;
2563{
2564 int i;
2565 int len;
2566 string type;
2567 const char *tem;
2568
2569 string_appendn (declp, (*mangled), scan - (*mangled));
2570 string_need (declp, 1);
2571 *(declp -> p) = '\0';
2572
2573 /* Consume the function name, including the "__" separating the name
2574 from the signature. We are guaranteed that SCAN points to the
0f41302f 2575 separator. */
a3184468
JM
2576
2577 (*mangled) = scan + 2;
2578
2579 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2580 {
2581
2582 /* See if we have an ARM style constructor or destructor operator.
2583 If so, then just record it, clear the decl, and return.
2584 We can't build the actual constructor/destructor decl until later,
0f41302f 2585 when we recover the class name from the signature. */
a3184468
JM
2586
2587 if (strcmp (declp -> b, "__ct") == 0)
2588 {
2589 work -> constructor += 1;
2590 string_clear (declp);
2591 return;
2592 }
2593 else if (strcmp (declp -> b, "__dt") == 0)
2594 {
2595 work -> destructor += 1;
2596 string_clear (declp);
2597 return;
2598 }
2599 }
2600
2601 if (declp->p - declp->b >= 3
2602 && declp->b[0] == 'o'
2603 && declp->b[1] == 'p'
2604 && strchr (cplus_markers, declp->b[2]) != NULL)
2605 {
2606 /* see if it's an assignment expression */
2607 if (declp->p - declp->b >= 10 /* op$assign_ */
2608 && memcmp (declp->b + 3, "assign_", 7) == 0)
2609 {
2610 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2611 {
2612 len = declp->p - declp->b - 10;
2613 if (strlen (optable[i].in) == len
2614 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2615 {
2616 string_clear (declp);
2617 string_append (declp, "operator");
2618 string_append (declp, optable[i].out);
2619 string_append (declp, "=");
2620 break;
2621 }
2622 }
2623 }
2624 else
2625 {
2626 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2627 {
2628 int len = declp->p - declp->b - 3;
2629 if (strlen (optable[i].in) == len
2630 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2631 {
2632 string_clear (declp);
2633 string_append (declp, "operator");
2634 string_append (declp, optable[i].out);
2635 break;
2636 }
2637 }
2638 }
2639 }
2640 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2641 && strchr (cplus_markers, declp->b[4]) != NULL)
2642 {
2643 /* type conversion operator */
2644 tem = declp->b + 5;
2645 if (do_type (work, &tem, &type))
2646 {
2647 string_clear (declp);
2648 string_append (declp, "operator ");
2649 string_appends (declp, &type);
2650 string_delete (&type);
2651 }
2652 }
2653 else if (declp->b[0] == '_' && declp->b[1] == '_'
5d644692 2654 && declp->b[2] == 'o' && declp->b[3] == 'p')
a3184468
JM
2655 {
2656 /* ANSI. */
2657 /* type conversion operator. */
2658 tem = declp->b + 4;
2659 if (do_type (work, &tem, &type))
2660 {
2661 string_clear (declp);
2662 string_append (declp, "operator ");
2663 string_appends (declp, &type);
2664 string_delete (&type);
2665 }
2666 }
2667 else if (declp->b[0] == '_' && declp->b[1] == '_'
2668 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2669 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2670 {
2671 if (declp->b[4] == '\0')
2672 {
2673 /* Operator. */
2674 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2675 {
2676 if (strlen (optable[i].in) == 2
2677 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2678 {
2679 string_clear (declp);
2680 string_append (declp, "operator");
2681 string_append (declp, optable[i].out);
2682 break;
2683 }
2684 }
2685 }
2686 else
2687 {
2688 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2689 {
0f41302f 2690 /* Assignment. */
a3184468
JM
2691 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2692 {
2693 if (strlen (optable[i].in) == 3
2694 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2695 {
2696 string_clear (declp);
2697 string_append (declp, "operator");
2698 string_append (declp, optable[i].out);
2699 break;
2700 }
2701 }
2702 }
2703 }
2704 }
2705}
2706
2707/* a mini string-handling package */
2708
2709static void
2710string_need (s, n)
2711 string *s;
2712 int n;
2713{
2714 int tem;
2715
2716 if (s->b == NULL)
2717 {
2718 if (n < 32)
2719 {
2720 n = 32;
2721 }
2722 s->p = s->b = xmalloc (n);
2723 s->e = s->b + n;
2724 }
2725 else if (s->e - s->p < n)
2726 {
2727 tem = s->p - s->b;
2728 n += tem;
2729 n *= 2;
2730 s->b = xrealloc (s->b, n);
2731 s->p = s->b + tem;
2732 s->e = s->b + n;
2733 }
2734}
2735
2736static void
2737string_delete (s)
2738 string *s;
2739{
2740 if (s->b != NULL)
2741 {
2742 free (s->b);
2743 s->b = s->e = s->p = NULL;
2744 }
2745}
2746
2747static void
2748string_init (s)
2749 string *s;
2750{
2751 s->b = s->p = s->e = NULL;
2752}
2753
2754static void
2755string_clear (s)
2756 string *s;
2757{
2758 s->p = s->b;
2759}
2760
2761#if 0
2762
2763static int
2764string_empty (s)
2765 string *s;
2766{
2767 return (s->b == s->p);
2768}
2769
2770#endif
2771
2772static void
2773string_append (p, s)
2774 string *p;
2775 const char *s;
2776{
2777 int n;
2778 if (s == NULL || *s == '\0')
2779 return;
2780 n = strlen (s);
2781 string_need (p, n);
2782 memcpy (p->p, s, n);
2783 p->p += n;
2784}
2785
2786static void
2787string_appends (p, s)
2788 string *p, *s;
2789{
2790 int n;
2791
2792 if (s->b != s->p)
2793 {
2794 n = s->p - s->b;
2795 string_need (p, n);
2796 memcpy (p->p, s->b, n);
2797 p->p += n;
2798 }
2799}
2800
2801static void
2802string_appendn (p, s, n)
2803 string *p;
2804 const char *s;
2805 int n;
2806{
2807 if (n != 0)
2808 {
2809 string_need (p, n);
2810 memcpy (p->p, s, n);
2811 p->p += n;
2812 }
2813}
2814
2815static void
2816string_prepend (p, s)
2817 string *p;
2818 const char *s;
2819{
2820 if (s != NULL && *s != '\0')
2821 {
2822 string_prependn (p, s, strlen (s));
2823 }
2824}
2825
2826static void
2827string_prepends (p, s)
2828 string *p, *s;
2829{
2830 if (s->b != s->p)
2831 {
2832 string_prependn (p, s->b, s->p - s->b);
2833 }
2834}
2835
2836static void
2837string_prependn (p, s, n)
2838 string *p;
2839 const char *s;
2840 int n;
2841{
2842 char *q;
2843
2844 if (n != 0)
2845 {
2846 string_need (p, n);
2847 for (q = p->p - 1; q >= p->b; q--)
2848 {
2849 q[n] = q[0];
2850 }
2851 memcpy (p->b, s, n);
2852 p->p += n;
2853 }
2854}
2855
2856/* To generate a standalone demangler program for testing purposes,
2857 just compile and link this file with -DMAIN and libiberty.a. When
2858 run, it demangles each command line arg, or each stdin string, and
0f41302f 2859 prints the result on stdout. */
a3184468
JM
2860
2861#ifdef MAIN
2862
2863static void
2864demangle_it (mangled_name)
5d644692 2865 char *mangled_name;
a3184468
JM
2866{
2867 char *result;
2868
2869 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2870 if (result == NULL)
2871 {
2872 printf ("%s\n", mangled_name);
2873 }
2874 else
2875 {
2876 printf ("%s\n", result);
2877 free (result);
2878 }
2879}
2880
2881#include "getopt.h"
2882
2883static char *program_name;
2884static char *program_version = VERSION;
2885
2886static void
2887usage (stream, status)
2888 FILE *stream;
2889 int status;
2890{
2891 fprintf (stream, "\
2892Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
5d644692
MS
2893 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2894 [--help] [--version] [arg...]\n",
a3184468
JM
2895 program_name);
2896 exit (status);
2897}
2898
2899#define MBUF_SIZE 512
2900char mbuffer[MBUF_SIZE];
2901
0f41302f 2902/* Defined in the automatically-generated underscore.c. */
a3184468
JM
2903extern int prepends_underscore;
2904
2905int strip_underscore = 0;
2906
2907static struct option long_options[] = {
2908 {"strip-underscores", no_argument, 0, '_'},
2909 {"format", required_argument, 0, 's'},
2910 {"help", no_argument, 0, 'h'},
2911 {"no-strip-underscores", no_argument, 0, 'n'},
2912 {"version", no_argument, 0, 'v'},
2913 {0, no_argument, 0, 0}
2914};
2915
2916int
2917main (argc, argv)
2918 int argc;
2919 char **argv;
2920{
2921 char *result;
2922 int c;
2923
2924 program_name = argv[0];
2925
2926 strip_underscore = prepends_underscore;
2927
2928 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2929 {
2930 switch (c)
2931 {
5d644692
MS
2932 case '?':
2933 usage (stderr, 1);
2934 break;
2935 case 'h':
2936 usage (stdout, 0);
2937 case 'n':
2938 strip_underscore = 0;
2939 break;
2940 case 'v':
2941 printf ("GNU %s version %s\n", program_name, program_version);
2942 exit (0);
2943 case '_':
2944 strip_underscore = 1;
2945 break;
2946 case 's':
2947 if (strcmp (optarg, "gnu") == 0)
2948 {
2949 current_demangling_style = gnu_demangling;
2950 }
2951 else if (strcmp (optarg, "lucid") == 0)
2952 {
2953 current_demangling_style = lucid_demangling;
2954 }
2955 else if (strcmp (optarg, "arm") == 0)
2956 {
2957 current_demangling_style = arm_demangling;
2958 }
2959 else
2960 {
2961 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2962 program_name, optarg);
2963 exit (1);
2964 }
2965 break;
a3184468
JM
2966 }
2967 }
2968
2969 if (optind < argc)
2970 {
2971 for ( ; optind < argc; optind++)
2972 {
2973 demangle_it (argv[optind]);
2974 }
2975 }
2976 else
2977 {
2978 for (;;)
2979 {
2980 int i = 0;
2981 c = getchar ();
0f41302f 2982 /* Try to read a label. */
a3184468
JM
2983 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2984 {
2985 if (i >= MBUF_SIZE-1)
2986 break;
2987 mbuffer[i++] = c;
2988 c = getchar ();
2989 }
2990 if (i > 0)
2991 {
2992 int skip_first = 0;
2993
2994 if (mbuffer[0] == '.')
2995 ++skip_first;
2996 if (strip_underscore && mbuffer[skip_first] == '_')
2997 ++skip_first;
2998
2999 if (skip_first > i)
3000 skip_first = i;
3001
3002 mbuffer[i] = 0;
3003
3004 result = cplus_demangle (mbuffer + skip_first,
3005 DMGL_PARAMS | DMGL_ANSI);
3006 if (result)
3007 {
3008 if (mbuffer[0] == '.')
3009 putc ('.', stdout);
3010 fputs (result, stdout);
3011 free (result);
3012 }
3013 else
3014 fputs (mbuffer, stdout);
3015
3016 fflush (stdout);
3017 }
3018 if (c == EOF)
3019 break;
3020 putchar (c);
3021 }
3022 }
3023
3024 exit (0);
3025}
3026
3027static void
3028fatal (str)
3029 char *str;
3030{
3031 fprintf (stderr, "%s: %s\n", program_name, str);
3032 exit (1);
3033}
3034
3035char * malloc ();
3036char * realloc ();
3037
3038char *
3039xmalloc (size)
3040 unsigned size;
3041{
3042 register char *value = (char *) malloc (size);
3043 if (value == 0)
3044 fatal ("virtual memory exhausted");
3045 return value;
3046}
3047
3048char *
3049xrealloc (ptr, size)
3050 char *ptr;
3051 unsigned size;
3052{
3053 register char *value = (char *) realloc (ptr, size);
3054 if (value == 0)
3055 fatal ("virtual memory exhausted");
3056 return value;
3057}
3058#endif /* main */
This page took 0.41369 seconds and 5 git commands to generate.