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