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