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