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