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