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