cplus-dem.c (demangle_qualified): Fix off-by-one when checking range of 'K' index.
[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 ((unsigned char)**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 ((unsigned char)**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 ((int) 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 ((int) 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 ((int) 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 ((unsigned char)**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 ((unsigned char)**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 ((unsigned char)**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 ((unsigned char)**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 = 0;
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
1425 || (int) strlen (*mangled) < r)
1426 {
1427 return (0);
1428 }
1429 string_appendn (tname, *mangled, r);
1430 if (trawname)
1431 string_appendn (trawname, *mangled, r);
1432 *mangled += r;
1433 }
1434 }
1435 string_append (tname, "<");
1436 /* get size of template parameter list */
1437 if (!get_count (mangled, &r))
1438 {
1439 return (0);
1440 }
1441 if (!is_type)
1442 {
1443 /* Create an array for saving the template argument values. */
1444 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1445 work->ntmpl_args = r;
1446 for (i = 0; i < r; i++)
1447 work->tmpl_argvec[i] = 0;
1448 }
1449 for (i = 0; i < r; i++)
1450 {
1451 if (need_comma)
1452 {
1453 string_append (tname, ", ");
1454 }
1455 /* Z for type parameters */
1456 if (**mangled == 'Z')
1457 {
1458 (*mangled)++;
1459 /* temp is initialized in do_type */
1460 success = do_type (work, mangled, &temp);
1461 if (success)
1462 {
1463 string_appends (tname, &temp);
1464
1465 if (!is_type)
1466 {
1467 /* Save the template argument. */
1468 int len = temp.p - temp.b;
1469 work->tmpl_argvec[i] = xmalloc (len + 1);
1470 memcpy (work->tmpl_argvec[i], temp.b, len);
1471 work->tmpl_argvec[i][len] = '\0';
1472 }
1473 }
1474 string_delete(&temp);
1475 if (!success)
1476 {
1477 break;
1478 }
1479 }
1480 /* z for template parameters */
1481 else if (**mangled == 'z')
1482 {
1483 int r2;
1484 (*mangled)++;
1485 success = demangle_template_template_parm (work, mangled, tname);
1486
1487 if (success
1488 && (r2 = consume_count (mangled)) > 0
1489 && (int) strlen (*mangled) >= r2)
1490 {
1491 string_append (tname, " ");
1492 string_appendn (tname, *mangled, r2);
1493 if (!is_type)
1494 {
1495 /* Save the template argument. */
1496 int len = r2;
1497 work->tmpl_argvec[i] = xmalloc (len + 1);
1498 memcpy (work->tmpl_argvec[i], *mangled, len);
1499 work->tmpl_argvec[i][len] = '\0';
1500 }
1501 *mangled += r2;
1502 }
1503 if (!success)
1504 {
1505 break;
1506 }
1507 }
1508 else
1509 {
1510 string param;
1511 string* s;
1512
1513 /* otherwise, value parameter */
1514
1515 /* temp is initialized in do_type */
1516 success = do_type (work, mangled, &temp);
1517 string_delete(&temp);
1518 if (!success)
1519 break;
1520
1521 if (!is_type)
1522 {
1523 s = &param;
1524 string_init (s);
1525 }
1526 else
1527 s = tname;
1528
1529 success = demangle_template_value_parm (work, mangled, s,
1530 (type_kind_t) success);
1531
1532 if (!success)
1533 {
1534 if (!is_type)
1535 string_delete (s);
1536 success = 0;
1537 break;
1538 }
1539
1540 if (!is_type)
1541 {
1542 int len = s->p - s->b;
1543 work->tmpl_argvec[i] = xmalloc (len + 1);
1544 memcpy (work->tmpl_argvec[i], s->b, len);
1545 work->tmpl_argvec[i][len] = '\0';
1546
1547 string_appends (tname, s);
1548 string_delete (s);
1549 }
1550 }
1551 need_comma = 1;
1552 }
1553 {
1554 if (tname->p[-1] == '>')
1555 string_append (tname, " ");
1556 string_append (tname, ">");
1557 }
1558
1559 if (is_type && remember)
1560 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1561
1562 /*
1563 if (work -> static_type)
1564 {
1565 string_append (declp, *mangled + 1);
1566 *mangled += strlen (*mangled);
1567 success = 1;
1568 }
1569 else
1570 {
1571 success = demangle_args (work, mangled, declp);
1572 }
1573 }
1574 */
1575 return (success);
1576 }
1577
1578 static int
1579 arm_pt (work, mangled, n, anchor, args)
1580 struct work_stuff *work;
1581 const char *mangled;
1582 int n;
1583 const char **anchor, **args;
1584 {
1585 /* ARM template? */
1586 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1587 {
1588 int len;
1589 *args = *anchor + 6;
1590 len = consume_count (args);
1591 if (*args + len == mangled + n && **args == '_')
1592 {
1593 ++*args;
1594 return 1;
1595 }
1596 }
1597 return 0;
1598 }
1599
1600 static void
1601 demangle_arm_pt (work, mangled, n, declp)
1602 struct work_stuff *work;
1603 const char **mangled;
1604 int n;
1605 string *declp;
1606 {
1607 const char *p;
1608 const char *args;
1609 const char *e = *mangled + n;
1610
1611 /* ARM template? */
1612 if (arm_pt (work, *mangled, n, &p, &args))
1613 {
1614 string arg;
1615 string_init (&arg);
1616 string_appendn (declp, *mangled, p - *mangled);
1617 string_append (declp, "<");
1618 /* should do error checking here */
1619 while (args < e) {
1620 string_clear (&arg);
1621 do_type (work, &args, &arg);
1622 string_appends (declp, &arg);
1623 string_append (declp, ",");
1624 }
1625 string_delete (&arg);
1626 --declp->p;
1627 string_append (declp, ">");
1628 }
1629 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1630 && (*mangled)[9] == 'N'
1631 && (*mangled)[8] == (*mangled)[10]
1632 && strchr (cplus_markers, (*mangled)[8]))
1633 {
1634 /* A member of the anonymous namespace. */
1635 string_append (declp, "{anonymous}");
1636 }
1637 else
1638 {
1639 string_appendn (declp, *mangled, n);
1640 }
1641 *mangled += n;
1642 }
1643
1644 static int
1645 demangle_class_name (work, mangled, declp)
1646 struct work_stuff *work;
1647 const char **mangled;
1648 string *declp;
1649 {
1650 int n;
1651 int success = 0;
1652
1653 n = consume_count (mangled);
1654 if ((int) strlen (*mangled) >= n)
1655 {
1656 demangle_arm_pt (work, mangled, n, declp);
1657 success = 1;
1658 }
1659
1660 return (success);
1661 }
1662
1663 /*
1664
1665 LOCAL FUNCTION
1666
1667 demangle_class -- demangle a mangled class sequence
1668
1669 SYNOPSIS
1670
1671 static int
1672 demangle_class (struct work_stuff *work, const char **mangled,
1673 strint *declp)
1674
1675 DESCRIPTION
1676
1677 DECLP points to the buffer into which demangling is being done.
1678
1679 *MANGLED points to the current token to be demangled. On input,
1680 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1681 On exit, it points to the next token after the mangled class on
1682 success, or the first unconsumed token on failure.
1683
1684 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1685 we are demangling a constructor or destructor. In this case
1686 we prepend "class::class" or "class::~class" to DECLP.
1687
1688 Otherwise, we prepend "class::" to the current DECLP.
1689
1690 Reset the constructor/destructor flags once they have been
1691 "consumed". This allows demangle_class to be called later during
1692 the same demangling, to do normal class demangling.
1693
1694 Returns 1 if demangling is successful, 0 otherwise.
1695
1696 */
1697
1698 static int
1699 demangle_class (work, mangled, declp)
1700 struct work_stuff *work;
1701 const char **mangled;
1702 string *declp;
1703 {
1704 int success = 0;
1705 int btype;
1706 string class_name;
1707
1708 string_init (&class_name);
1709 btype = register_Btype (work);
1710 if (demangle_class_name (work, mangled, &class_name))
1711 {
1712 if ((work->constructor & 1) || (work->destructor & 1))
1713 {
1714 string_prepends (declp, &class_name);
1715 if (work -> destructor & 1)
1716 {
1717 string_prepend (declp, "~");
1718 work -> destructor -= 1;
1719 }
1720 else
1721 {
1722 work -> constructor -= 1;
1723 }
1724 }
1725 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
1726 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
1727 string_prepend (declp, SCOPE_STRING (work));
1728 string_prepends (declp, &class_name);
1729 success = 1;
1730 }
1731 string_delete (&class_name);
1732 return (success);
1733 }
1734
1735 /*
1736
1737 LOCAL FUNCTION
1738
1739 demangle_prefix -- consume the mangled name prefix and find signature
1740
1741 SYNOPSIS
1742
1743 static int
1744 demangle_prefix (struct work_stuff *work, const char **mangled,
1745 string *declp);
1746
1747 DESCRIPTION
1748
1749 Consume and demangle the prefix of the mangled name.
1750
1751 DECLP points to the string buffer into which demangled output is
1752 placed. On entry, the buffer is empty. On exit it contains
1753 the root function name, the demangled operator name, or in some
1754 special cases either nothing or the completely demangled result.
1755
1756 MANGLED points to the current pointer into the mangled name. As each
1757 token of the mangled name is consumed, it is updated. Upon entry
1758 the current mangled name pointer points to the first character of
1759 the mangled name. Upon exit, it should point to the first character
1760 of the signature if demangling was successful, or to the first
1761 unconsumed character if demangling of the prefix was unsuccessful.
1762
1763 Returns 1 on success, 0 otherwise.
1764 */
1765
1766 static int
1767 demangle_prefix (work, mangled, declp)
1768 struct work_stuff *work;
1769 const char **mangled;
1770 string *declp;
1771 {
1772 int success = 1;
1773 const char *scan;
1774 int i;
1775
1776 if (strlen(*mangled) > 6
1777 && (strncmp(*mangled, "_imp__", 6) == 0
1778 || strncmp(*mangled, "__imp_", 6) == 0))
1779 {
1780 /* it's a symbol imported from a PE dynamic library. Check for both
1781 new style prefix _imp__ and legacy __imp_ used by older versions
1782 of dlltool. */
1783 (*mangled) += 6;
1784 work->dllimported = 1;
1785 }
1786 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1787 {
1788 char *marker = strchr (cplus_markers, (*mangled)[8]);
1789 if (marker != NULL && *marker == (*mangled)[10])
1790 {
1791 if ((*mangled)[9] == 'D')
1792 {
1793 /* it's a GNU global destructor to be executed at program exit */
1794 (*mangled) += 11;
1795 work->destructor = 2;
1796 if (gnu_special (work, mangled, declp))
1797 return success;
1798 }
1799 else if ((*mangled)[9] == 'I')
1800 {
1801 /* it's a GNU global constructor to be executed at program init */
1802 (*mangled) += 11;
1803 work->constructor = 2;
1804 if (gnu_special (work, mangled, declp))
1805 return success;
1806 }
1807 }
1808 }
1809 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1810 {
1811 /* it's a ARM global destructor to be executed at program exit */
1812 (*mangled) += 7;
1813 work->destructor = 2;
1814 }
1815 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1816 {
1817 /* it's a ARM global constructor to be executed at program initial */
1818 (*mangled) += 7;
1819 work->constructor = 2;
1820 }
1821
1822 /* This block of code is a reduction in strength time optimization
1823 of:
1824 scan = mystrstr (*mangled, "__"); */
1825
1826 {
1827 scan = *mangled;
1828
1829 do {
1830 scan = strchr (scan, '_');
1831 } while (scan != NULL && *++scan != '_');
1832
1833 if (scan != NULL) --scan;
1834 }
1835
1836 if (scan != NULL)
1837 {
1838 /* We found a sequence of two or more '_', ensure that we start at
1839 the last pair in the sequence. */
1840 i = strspn (scan, "_");
1841 if (i > 2)
1842 {
1843 scan += (i - 2);
1844 }
1845 }
1846
1847 if (scan == NULL)
1848 {
1849 success = 0;
1850 }
1851 else if (work -> static_type)
1852 {
1853 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
1854 {
1855 success = 0;
1856 }
1857 }
1858 else if ((scan == *mangled)
1859 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
1860 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
1861 {
1862 /* The ARM says nothing about the mangling of local variables.
1863 But cfront mangles local variables by prepending __<nesting_level>
1864 to them. As an extension to ARM demangling we handle this case. */
1865 if ((LUCID_DEMANGLING || ARM_DEMANGLING)
1866 && isdigit ((unsigned char)scan[2]))
1867 {
1868 *mangled = scan + 2;
1869 consume_count (mangled);
1870 string_append (declp, *mangled);
1871 *mangled += strlen (*mangled);
1872 success = 1;
1873 }
1874 else
1875 {
1876 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1877 names like __Q2_3foo3bar for nested type names. So don't accept
1878 this style of constructor for cfront demangling. A GNU
1879 style member-template constructor starts with 'H'. */
1880 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1881 work -> constructor += 1;
1882 *mangled = scan + 2;
1883 }
1884 }
1885 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
1886 && (scan[2] != 't'))
1887 {
1888 /* Mangled name starts with "__". Skip over any leading '_' characters,
1889 then find the next "__" that separates the prefix from the signature.
1890 */
1891 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1892 || (arm_special (mangled, declp) == 0))
1893 {
1894 while (*scan == '_')
1895 {
1896 scan++;
1897 }
1898 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1899 {
1900 /* No separator (I.E. "__not_mangled"), or empty signature
1901 (I.E. "__not_mangled_either__") */
1902 success = 0;
1903 }
1904 else
1905 {
1906 demangle_function_name (work, mangled, declp, scan);
1907 }
1908 }
1909 }
1910 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1911 {
1912 /* Cfront-style parameterized type. Handled later as a signature. */
1913 success = 1;
1914
1915 /* ARM template? */
1916 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1917 }
1918 else if (*(scan + 2) != '\0')
1919 {
1920 /* Mangled name does not start with "__" but does have one somewhere
1921 in there with non empty stuff after it. Looks like a global
1922 function name. */
1923 demangle_function_name (work, mangled, declp, scan);
1924 }
1925 else
1926 {
1927 /* Doesn't look like a mangled name */
1928 success = 0;
1929 }
1930
1931 if (!success && (work->constructor == 2 || work->destructor == 2))
1932 {
1933 string_append (declp, *mangled);
1934 *mangled += strlen (*mangled);
1935 success = 1;
1936 }
1937 return (success);
1938 }
1939
1940 /*
1941
1942 LOCAL FUNCTION
1943
1944 gnu_special -- special handling of gnu mangled strings
1945
1946 SYNOPSIS
1947
1948 static int
1949 gnu_special (struct work_stuff *work, const char **mangled,
1950 string *declp);
1951
1952
1953 DESCRIPTION
1954
1955 Process some special GNU style mangling forms that don't fit
1956 the normal pattern. For example:
1957
1958 _$_3foo (destructor for class foo)
1959 _vt$foo (foo virtual table)
1960 _vt$foo$bar (foo::bar virtual table)
1961 __vt_foo (foo virtual table, new style with thunks)
1962 _3foo$varname (static data member)
1963 _Q22rs2tu$vw (static data member)
1964 __t6vector1Zii (constructor with template)
1965 __thunk_4__$_7ostream (virtual function thunk)
1966 */
1967
1968 static int
1969 gnu_special (work, mangled, declp)
1970 struct work_stuff *work;
1971 const char **mangled;
1972 string *declp;
1973 {
1974 int n;
1975 int success = 1;
1976 const char *p;
1977
1978 if ((*mangled)[0] == '_'
1979 && strchr (cplus_markers, (*mangled)[1]) != NULL
1980 && (*mangled)[2] == '_')
1981 {
1982 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1983 (*mangled) += 3;
1984 work -> destructor += 1;
1985 }
1986 else if ((*mangled)[0] == '_'
1987 && (((*mangled)[1] == '_'
1988 && (*mangled)[2] == 'v'
1989 && (*mangled)[3] == 't'
1990 && (*mangled)[4] == '_')
1991 || ((*mangled)[1] == 'v'
1992 && (*mangled)[2] == 't'
1993 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1994 {
1995 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1996 and create the decl. Note that we consume the entire mangled
1997 input string, which means that demangle_signature has no work
1998 to do. */
1999 if ((*mangled)[2] == 'v')
2000 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2001 else
2002 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2003 while (**mangled != '\0')
2004 {
2005 p = strpbrk (*mangled, cplus_markers);
2006 switch (**mangled)
2007 {
2008 case 'Q':
2009 case 'K':
2010 success = demangle_qualified (work, mangled, declp, 0, 1);
2011 break;
2012 case 't':
2013 success = demangle_template (work, mangled, declp, 0, 1,
2014 1);
2015 break;
2016 default:
2017 if (isdigit((unsigned char)*mangled[0]))
2018 {
2019 n = consume_count(mangled);
2020 /* We may be seeing a too-large size, or else a
2021 ".<digits>" indicating a static local symbol. In
2022 any case, declare victory and move on; *don't* try
2023 to use n to allocate. */
2024 if (n > (int) strlen (*mangled))
2025 {
2026 success = 1;
2027 break;
2028 }
2029 }
2030 else
2031 {
2032 n = strcspn (*mangled, cplus_markers);
2033 }
2034 string_appendn (declp, *mangled, n);
2035 (*mangled) += n;
2036 }
2037
2038 if (success && ((p == NULL) || (p == *mangled)))
2039 {
2040 if (p != NULL)
2041 {
2042 string_append (declp, SCOPE_STRING (work));
2043 (*mangled)++;
2044 }
2045 }
2046 else
2047 {
2048 success = 0;
2049 break;
2050 }
2051 }
2052 if (success)
2053 string_append (declp, " virtual table");
2054 }
2055 else if ((*mangled)[0] == '_'
2056 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2057 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2058 {
2059 /* static data member, "_3foo$varname" for example */
2060 (*mangled)++;
2061 switch (**mangled)
2062 {
2063 case 'Q':
2064 case 'K':
2065 success = demangle_qualified (work, mangled, declp, 0, 1);
2066 break;
2067 case 't':
2068 success = demangle_template (work, mangled, declp, 0, 1, 1);
2069 break;
2070 default:
2071 n = consume_count (mangled);
2072 string_appendn (declp, *mangled, n);
2073 (*mangled) += n;
2074 }
2075 if (success && (p == *mangled))
2076 {
2077 /* Consumed everything up to the cplus_marker, append the
2078 variable name. */
2079 (*mangled)++;
2080 string_append (declp, SCOPE_STRING (work));
2081 n = strlen (*mangled);
2082 string_appendn (declp, *mangled, n);
2083 (*mangled) += n;
2084 }
2085 else
2086 {
2087 success = 0;
2088 }
2089 }
2090 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2091 {
2092 int delta = ((*mangled) += 8, consume_count (mangled));
2093 char *method = internal_cplus_demangle (work, ++*mangled);
2094 if (method)
2095 {
2096 char buf[50];
2097 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2098 string_append (declp, buf);
2099 string_append (declp, method);
2100 free (method);
2101 n = strlen (*mangled);
2102 (*mangled) += n;
2103 }
2104 else
2105 {
2106 success = 0;
2107 }
2108 }
2109 else if (strncmp (*mangled, "__t", 3) == 0
2110 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2111 {
2112 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2113 (*mangled) += 4;
2114 switch (**mangled)
2115 {
2116 case 'Q':
2117 case 'K':
2118 success = demangle_qualified (work, mangled, declp, 0, 1);
2119 break;
2120 case 't':
2121 success = demangle_template (work, mangled, declp, 0, 1, 1);
2122 break;
2123 default:
2124 success = demangle_fund_type (work, mangled, declp);
2125 break;
2126 }
2127 if (success && **mangled != '\0')
2128 success = 0;
2129 if (success)
2130 string_append (declp, p);
2131 }
2132 else
2133 {
2134 success = 0;
2135 }
2136 return (success);
2137 }
2138
2139 /*
2140
2141 LOCAL FUNCTION
2142
2143 arm_special -- special handling of ARM/lucid mangled strings
2144
2145 SYNOPSIS
2146
2147 static int
2148 arm_special (const char **mangled,
2149 string *declp);
2150
2151
2152 DESCRIPTION
2153
2154 Process some special ARM style mangling forms that don't fit
2155 the normal pattern. For example:
2156
2157 __vtbl__3foo (foo virtual table)
2158 __vtbl__3foo__3bar (bar::foo virtual table)
2159
2160 */
2161
2162 static int
2163 arm_special (mangled, declp)
2164 const char **mangled;
2165 string *declp;
2166 {
2167 int n;
2168 int success = 1;
2169 const char *scan;
2170
2171 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2172 {
2173 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2174 and create the decl. Note that we consume the entire mangled
2175 input string, which means that demangle_signature has no work
2176 to do. */
2177 scan = *mangled + ARM_VTABLE_STRLEN;
2178 while (*scan != '\0') /* first check it can be demangled */
2179 {
2180 n = consume_count (&scan);
2181 if (n==0)
2182 {
2183 return (0); /* no good */
2184 }
2185 scan += n;
2186 if (scan[0] == '_' && scan[1] == '_')
2187 {
2188 scan += 2;
2189 }
2190 }
2191 (*mangled) += ARM_VTABLE_STRLEN;
2192 while (**mangled != '\0')
2193 {
2194 n = consume_count (mangled);
2195 string_prependn (declp, *mangled, n);
2196 (*mangled) += n;
2197 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2198 {
2199 string_prepend (declp, "::");
2200 (*mangled) += 2;
2201 }
2202 }
2203 string_append (declp, " virtual table");
2204 }
2205 else
2206 {
2207 success = 0;
2208 }
2209 return (success);
2210 }
2211
2212 /*
2213
2214 LOCAL FUNCTION
2215
2216 demangle_qualified -- demangle 'Q' qualified name strings
2217
2218 SYNOPSIS
2219
2220 static int
2221 demangle_qualified (struct work_stuff *, const char *mangled,
2222 string *result, int isfuncname, int append);
2223
2224 DESCRIPTION
2225
2226 Demangle a qualified name, such as "Q25Outer5Inner" which is
2227 the mangled form of "Outer::Inner". The demangled output is
2228 prepended or appended to the result string according to the
2229 state of the append flag.
2230
2231 If isfuncname is nonzero, then the qualified name we are building
2232 is going to be used as a member function name, so if it is a
2233 constructor or destructor function, append an appropriate
2234 constructor or destructor name. I.E. for the above example,
2235 the result for use as a constructor is "Outer::Inner::Inner"
2236 and the result for use as a destructor is "Outer::Inner::~Inner".
2237
2238 BUGS
2239
2240 Numeric conversion is ASCII dependent (FIXME).
2241
2242 */
2243
2244 static int
2245 demangle_qualified (work, mangled, result, isfuncname, append)
2246 struct work_stuff *work;
2247 const char **mangled;
2248 string *result;
2249 int isfuncname;
2250 int append;
2251 {
2252 int qualifiers = 0;
2253 int success = 1;
2254 const char *p;
2255 char num[2];
2256 string temp;
2257 string last_name;
2258 int bindex = register_Btype (work);
2259
2260 /* We only make use of ISFUNCNAME if the entity is a constructor or
2261 destructor. */
2262 isfuncname = (isfuncname
2263 && ((work->constructor & 1) || (work->destructor & 1)));
2264
2265 string_init (&temp);
2266 string_init (&last_name);
2267
2268 if ((*mangled)[0] == 'K')
2269 {
2270 /* Squangling qualified name reuse */
2271 int idx;
2272 (*mangled)++;
2273 idx = consume_count_with_underscores (mangled);
2274 if (idx == -1 || idx >= work -> numk)
2275 success = 0;
2276 else
2277 string_append (&temp, work -> ktypevec[idx]);
2278 }
2279 else
2280 switch ((*mangled)[1])
2281 {
2282 case '_':
2283 /* GNU mangled name with more than 9 classes. The count is preceded
2284 by an underscore (to distinguish it from the <= 9 case) and followed
2285 by an underscore. */
2286 p = *mangled + 2;
2287 qualifiers = atoi (p);
2288 if (!isdigit ((unsigned char)*p) || *p == '0')
2289 success = 0;
2290
2291 /* Skip the digits. */
2292 while (isdigit ((unsigned char)*p))
2293 ++p;
2294
2295 if (*p != '_')
2296 success = 0;
2297
2298 *mangled = p + 1;
2299 break;
2300
2301 case '1':
2302 case '2':
2303 case '3':
2304 case '4':
2305 case '5':
2306 case '6':
2307 case '7':
2308 case '8':
2309 case '9':
2310 /* The count is in a single digit. */
2311 num[0] = (*mangled)[1];
2312 num[1] = '\0';
2313 qualifiers = atoi (num);
2314
2315 /* If there is an underscore after the digit, skip it. This is
2316 said to be for ARM-qualified names, but the ARM makes no
2317 mention of such an underscore. Perhaps cfront uses one. */
2318 if ((*mangled)[2] == '_')
2319 {
2320 (*mangled)++;
2321 }
2322 (*mangled) += 2;
2323 break;
2324
2325 case '0':
2326 default:
2327 success = 0;
2328 }
2329
2330 if (!success)
2331 return success;
2332
2333 /* Pick off the names and collect them in the temp buffer in the order
2334 in which they are found, separated by '::'. */
2335
2336 while (qualifiers-- > 0)
2337 {
2338 int remember_K = 1;
2339 string_clear (&last_name);
2340
2341 if (*mangled[0] == '_')
2342 (*mangled)++;
2343
2344 if (*mangled[0] == 't')
2345 {
2346 /* Here we always append to TEMP since we will want to use
2347 the template name without the template parameters as a
2348 constructor or destructor name. The appropriate
2349 (parameter-less) value is returned by demangle_template
2350 in LAST_NAME. We do not remember the template type here,
2351 in order to match the G++ mangling algorithm. */
2352 success = demangle_template(work, mangled, &temp,
2353 &last_name, 1, 0);
2354 if (!success)
2355 break;
2356 }
2357 else if (*mangled[0] == 'K')
2358 {
2359 int idx;
2360 (*mangled)++;
2361 idx = consume_count_with_underscores (mangled);
2362 if (idx == -1 || idx >= work->numk)
2363 success = 0;
2364 else
2365 string_append (&temp, work->ktypevec[idx]);
2366 remember_K = 0;
2367
2368 if (!success) break;
2369 }
2370 else
2371 {
2372 success = do_type (work, mangled, &last_name);
2373 if (!success)
2374 break;
2375 string_appends (&temp, &last_name);
2376 }
2377
2378 if (remember_K)
2379 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2380
2381 if (qualifiers > 0)
2382 string_append (&temp, SCOPE_STRING (work));
2383 }
2384
2385 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2386
2387 /* If we are using the result as a function name, we need to append
2388 the appropriate '::' separated constructor or destructor name.
2389 We do this here because this is the most convenient place, where
2390 we already have a pointer to the name and the length of the name. */
2391
2392 if (isfuncname)
2393 {
2394 string_append (&temp, SCOPE_STRING (work));
2395 if (work -> destructor & 1)
2396 string_append (&temp, "~");
2397 string_appends (&temp, &last_name);
2398 }
2399
2400 /* Now either prepend the temp buffer to the result, or append it,
2401 depending upon the state of the append flag. */
2402
2403 if (append)
2404 string_appends (result, &temp);
2405 else
2406 {
2407 if (!STRING_EMPTY (result))
2408 string_append (&temp, SCOPE_STRING (work));
2409 string_prepends (result, &temp);
2410 }
2411
2412 string_delete (&last_name);
2413 string_delete (&temp);
2414 return (success);
2415 }
2416
2417 /*
2418
2419 LOCAL FUNCTION
2420
2421 get_count -- convert an ascii count to integer, consuming tokens
2422
2423 SYNOPSIS
2424
2425 static int
2426 get_count (const char **type, int *count)
2427
2428 DESCRIPTION
2429
2430 Return 0 if no conversion is performed, 1 if a string is converted.
2431 */
2432
2433 static int
2434 get_count (type, count)
2435 const char **type;
2436 int *count;
2437 {
2438 const char *p;
2439 int n;
2440
2441 if (!isdigit ((unsigned char)**type))
2442 {
2443 return (0);
2444 }
2445 else
2446 {
2447 *count = **type - '0';
2448 (*type)++;
2449 if (isdigit ((unsigned char)**type))
2450 {
2451 p = *type;
2452 n = *count;
2453 do
2454 {
2455 n *= 10;
2456 n += *p - '0';
2457 p++;
2458 }
2459 while (isdigit ((unsigned char)*p));
2460 if (*p == '_')
2461 {
2462 *type = p + 1;
2463 *count = n;
2464 }
2465 }
2466 }
2467 return (1);
2468 }
2469
2470 /* RESULT will be initialised here; it will be freed on failure. The
2471 value returned is really a type_kind_t. */
2472
2473 static int
2474 do_type (work, mangled, result)
2475 struct work_stuff *work;
2476 const char **mangled;
2477 string *result;
2478 {
2479 int n;
2480 int done;
2481 int success;
2482 string decl;
2483 const char *remembered_type;
2484 int constp;
2485 int volatilep;
2486 string btype;
2487 type_kind_t tk = tk_none;
2488
2489 string_init (&btype);
2490 string_init (&decl);
2491 string_init (result);
2492
2493 done = 0;
2494 success = 1;
2495 while (success && !done)
2496 {
2497 int member;
2498 switch (**mangled)
2499 {
2500
2501 /* A pointer type */
2502 case 'P':
2503 case 'p':
2504 (*mangled)++;
2505 string_prepend (&decl, "*");
2506 if (tk == tk_none)
2507 tk = tk_pointer;
2508 break;
2509
2510 /* A reference type */
2511 case 'R':
2512 (*mangled)++;
2513 string_prepend (&decl, "&");
2514 if (tk == tk_none)
2515 tk = tk_pointer;
2516 break;
2517
2518 /* An array */
2519 case 'A':
2520 {
2521 ++(*mangled);
2522 if (!STRING_EMPTY (&decl)
2523 && (decl.b[0] == '*' || decl.b[0] == '&'))
2524 {
2525 string_prepend (&decl, "(");
2526 string_append (&decl, ")");
2527 }
2528 string_append (&decl, "[");
2529 if (**mangled != '_')
2530 success = demangle_template_value_parm (work, mangled, &decl,
2531 tk_integral);
2532 if (**mangled == '_')
2533 ++(*mangled);
2534 string_append (&decl, "]");
2535 break;
2536 }
2537
2538 /* A back reference to a previously seen type */
2539 case 'T':
2540 (*mangled)++;
2541 if (!get_count (mangled, &n) || n >= work -> ntypes)
2542 {
2543 success = 0;
2544 }
2545 else
2546 {
2547 remembered_type = work -> typevec[n];
2548 mangled = &remembered_type;
2549 }
2550 break;
2551
2552 /* A function */
2553 case 'F':
2554 (*mangled)++;
2555 if (!STRING_EMPTY (&decl)
2556 && (decl.b[0] == '*' || decl.b[0] == '&'))
2557 {
2558 string_prepend (&decl, "(");
2559 string_append (&decl, ")");
2560 }
2561 /* After picking off the function args, we expect to either find the
2562 function return type (preceded by an '_') or the end of the
2563 string. */
2564 if (!demangle_nested_args (work, mangled, &decl)
2565 || (**mangled != '_' && **mangled != '\0'))
2566 {
2567 success = 0;
2568 break;
2569 }
2570 if (success && (**mangled == '_'))
2571 (*mangled)++;
2572 break;
2573
2574 case 'M':
2575 case 'O':
2576 {
2577 constp = 0;
2578 volatilep = 0;
2579
2580 member = **mangled == 'M';
2581 (*mangled)++;
2582 if (!isdigit ((unsigned char)**mangled) && **mangled != 't')
2583 {
2584 success = 0;
2585 break;
2586 }
2587
2588 string_append (&decl, ")");
2589 string_prepend (&decl, SCOPE_STRING (work));
2590 if (isdigit ((unsigned char)**mangled))
2591 {
2592 n = consume_count (mangled);
2593 if ((int) strlen (*mangled) < n)
2594 {
2595 success = 0;
2596 break;
2597 }
2598 string_prependn (&decl, *mangled, n);
2599 *mangled += n;
2600 }
2601 else
2602 {
2603 string temp;
2604 string_init (&temp);
2605 success = demangle_template (work, mangled, &temp,
2606 NULL, 1, 1);
2607 if (success)
2608 {
2609 string_prependn (&decl, temp.b, temp.p - temp.b);
2610 string_clear (&temp);
2611 }
2612 else
2613 break;
2614 }
2615 string_prepend (&decl, "(");
2616 if (member)
2617 {
2618 if (**mangled == 'C')
2619 {
2620 (*mangled)++;
2621 constp = 1;
2622 }
2623 if (**mangled == 'V')
2624 {
2625 (*mangled)++;
2626 volatilep = 1;
2627 }
2628 if (*(*mangled)++ != 'F')
2629 {
2630 success = 0;
2631 break;
2632 }
2633 }
2634 if ((member && !demangle_nested_args (work, mangled, &decl))
2635 || **mangled != '_')
2636 {
2637 success = 0;
2638 break;
2639 }
2640 (*mangled)++;
2641 if (! PRINT_ANSI_QUALIFIERS)
2642 {
2643 break;
2644 }
2645 if (constp)
2646 {
2647 APPEND_BLANK (&decl);
2648 string_append (&decl, "const");
2649 }
2650 if (volatilep)
2651 {
2652 APPEND_BLANK (&decl);
2653 string_append (&decl, "volatile");
2654 }
2655 break;
2656 }
2657 case 'G':
2658 (*mangled)++;
2659 break;
2660
2661 case 'C':
2662 case 'V':
2663 /*
2664 if ((*mangled)[1] == 'P')
2665 {
2666 */
2667 if (PRINT_ANSI_QUALIFIERS)
2668 {
2669 if (!STRING_EMPTY (&decl))
2670 {
2671 string_prepend (&decl, " ");
2672 }
2673 string_prepend (&decl,
2674 (**mangled) == 'C' ? "const" : "volatile");
2675 }
2676 (*mangled)++;
2677 break;
2678 /*
2679 }
2680 */
2681
2682 /* fall through */
2683 default:
2684 done = 1;
2685 break;
2686 }
2687 }
2688
2689 if (success) switch (**mangled)
2690 {
2691 /* A qualified name, such as "Outer::Inner". */
2692 case 'Q':
2693 case 'K':
2694 {
2695 success = demangle_qualified (work, mangled, result, 0, 1);
2696 break;
2697 }
2698
2699 /* A back reference to a previously seen squangled type */
2700 case 'B':
2701 (*mangled)++;
2702 if (!get_count (mangled, &n) || n >= work -> numb)
2703 success = 0;
2704 else
2705 string_append (result, work->btypevec[n]);
2706 break;
2707
2708 case 'X':
2709 case 'Y':
2710 /* A template parm. We substitute the corresponding argument. */
2711 {
2712 int idx;
2713
2714 (*mangled)++;
2715 idx = consume_count_with_underscores (mangled);
2716
2717 if (idx == -1
2718 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2719 || consume_count_with_underscores (mangled) == -1)
2720 {
2721 success = 0;
2722 break;
2723 }
2724
2725 if (work->tmpl_argvec)
2726 string_append (result, work->tmpl_argvec[idx]);
2727 else
2728 {
2729 char buf[10];
2730 sprintf(buf, "T%d", idx);
2731 string_append (result, buf);
2732 }
2733
2734 success = 1;
2735 }
2736 break;
2737
2738 default:
2739 success = demangle_fund_type (work, mangled, result);
2740 if (tk == tk_none)
2741 tk = (type_kind_t) success;
2742 break;
2743 }
2744
2745 if (success)
2746 {
2747 if (!STRING_EMPTY (&decl))
2748 {
2749 string_append (result, " ");
2750 string_appends (result, &decl);
2751 }
2752 }
2753 else
2754 string_delete (result);
2755 string_delete (&decl);
2756
2757 if (success)
2758 /* Assume an integral type, if we're not sure. */
2759 return (int) ((tk == tk_none) ? tk_integral : tk);
2760 else
2761 return 0;
2762 }
2763
2764 /* Given a pointer to a type string that represents a fundamental type
2765 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2766 string in which the demangled output is being built in RESULT, and
2767 the WORK structure, decode the types and add them to the result.
2768
2769 For example:
2770
2771 "Ci" => "const int"
2772 "Sl" => "signed long"
2773 "CUs" => "const unsigned short"
2774
2775 The value returned is really a type_kind_t. */
2776
2777 static int
2778 demangle_fund_type (work, mangled, result)
2779 struct work_stuff *work;
2780 const char **mangled;
2781 string *result;
2782 {
2783 int done = 0;
2784 int success = 1;
2785 string btype;
2786 type_kind_t tk = tk_integral;
2787
2788 string_init (&btype);
2789
2790 /* First pick off any type qualifiers. There can be more than one. */
2791
2792 while (!done)
2793 {
2794 switch (**mangled)
2795 {
2796 case 'C':
2797 (*mangled)++;
2798 if (PRINT_ANSI_QUALIFIERS)
2799 {
2800 APPEND_BLANK (result);
2801 string_append (result, "const");
2802 }
2803 break;
2804 case 'U':
2805 (*mangled)++;
2806 APPEND_BLANK (result);
2807 string_append (result, "unsigned");
2808 break;
2809 case 'S': /* signed char only */
2810 (*mangled)++;
2811 APPEND_BLANK (result);
2812 string_append (result, "signed");
2813 break;
2814 case 'V':
2815 (*mangled)++;
2816 if (PRINT_ANSI_QUALIFIERS)
2817 {
2818 APPEND_BLANK (result);
2819 string_append (result, "volatile");
2820 }
2821 break;
2822 case 'J':
2823 (*mangled)++;
2824 APPEND_BLANK (result);
2825 string_append (result, "__complex");
2826 break;
2827 default:
2828 done = 1;
2829 break;
2830 }
2831 }
2832
2833 /* Now pick off the fundamental type. There can be only one. */
2834
2835 switch (**mangled)
2836 {
2837 case '\0':
2838 case '_':
2839 break;
2840 case 'v':
2841 (*mangled)++;
2842 APPEND_BLANK (result);
2843 string_append (result, "void");
2844 break;
2845 case 'x':
2846 (*mangled)++;
2847 APPEND_BLANK (result);
2848 string_append (result, "long long");
2849 break;
2850 case 'l':
2851 (*mangled)++;
2852 APPEND_BLANK (result);
2853 string_append (result, "long");
2854 break;
2855 case 'i':
2856 (*mangled)++;
2857 APPEND_BLANK (result);
2858 string_append (result, "int");
2859 break;
2860 case 's':
2861 (*mangled)++;
2862 APPEND_BLANK (result);
2863 string_append (result, "short");
2864 break;
2865 case 'b':
2866 (*mangled)++;
2867 APPEND_BLANK (result);
2868 string_append (result, "bool");
2869 tk = tk_bool;
2870 break;
2871 case 'c':
2872 (*mangled)++;
2873 APPEND_BLANK (result);
2874 string_append (result, "char");
2875 tk = tk_char;
2876 break;
2877 case 'w':
2878 (*mangled)++;
2879 APPEND_BLANK (result);
2880 string_append (result, "wchar_t");
2881 tk = tk_char;
2882 break;
2883 case 'r':
2884 (*mangled)++;
2885 APPEND_BLANK (result);
2886 string_append (result, "long double");
2887 tk = tk_real;
2888 break;
2889 case 'd':
2890 (*mangled)++;
2891 APPEND_BLANK (result);
2892 string_append (result, "double");
2893 tk = tk_real;
2894 break;
2895 case 'f':
2896 (*mangled)++;
2897 APPEND_BLANK (result);
2898 string_append (result, "float");
2899 tk = tk_real;
2900 break;
2901 case 'G':
2902 (*mangled)++;
2903 if (!isdigit ((unsigned char)**mangled))
2904 {
2905 success = 0;
2906 break;
2907 }
2908 /* fall through */
2909 /* An explicit type, such as "6mytype" or "7integer" */
2910 case '0':
2911 case '1':
2912 case '2':
2913 case '3':
2914 case '4':
2915 case '5':
2916 case '6':
2917 case '7':
2918 case '8':
2919 case '9':
2920 {
2921 int bindex = register_Btype (work);
2922 string btype;
2923 string_init (&btype);
2924 if (demangle_class_name (work, mangled, &btype)) {
2925 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
2926 APPEND_BLANK (result);
2927 string_appends (result, &btype);
2928 }
2929 else
2930 success = 0;
2931 string_delete (&btype);
2932 break;
2933 }
2934 case 't':
2935 {
2936 success = demangle_template (work, mangled, &btype, 0, 1, 1);
2937 string_appends (result, &btype);
2938 break;
2939 }
2940 default:
2941 success = 0;
2942 break;
2943 }
2944
2945 return success ? ((int) tk) : 0;
2946 }
2947
2948 /* Demangle the next argument, given by MANGLED into RESULT, which
2949 *should be an uninitialized* string. It will be initialized here,
2950 and free'd should anything go wrong. */
2951
2952 static int
2953 do_arg (work, mangled, result)
2954 struct work_stuff *work;
2955 const char **mangled;
2956 string *result;
2957 {
2958 /* Remember where we started so that we can record the type, for
2959 non-squangling type remembering. */
2960 const char *start = *mangled;
2961
2962 string_init (result);
2963
2964 if (work->nrepeats > 0)
2965 {
2966 --work->nrepeats;
2967
2968 if (work->previous_argument == 0)
2969 return 0;
2970
2971 /* We want to reissue the previous type in this argument list. */
2972 string_appends (result, work->previous_argument);
2973 return 1;
2974 }
2975
2976 if (**mangled == 'n')
2977 {
2978 /* A squangling-style repeat. */
2979 (*mangled)++;
2980 work->nrepeats = consume_count(mangled);
2981
2982 if (work->nrepeats == 0)
2983 /* This was not a repeat count after all. */
2984 return 0;
2985
2986 if (work->nrepeats > 9)
2987 {
2988 if (**mangled != '_')
2989 /* The repeat count should be followed by an '_' in this
2990 case. */
2991 return 0;
2992 else
2993 (*mangled)++;
2994 }
2995
2996 /* Now, the repeat is all set up. */
2997 return do_arg (work, mangled, result);
2998 }
2999
3000 /* Save the result in WORK->previous_argument so that we can find it
3001 if it's repeated. Note that saving START is not good enough: we
3002 do not want to add additional types to the back-referenceable
3003 type vector when processing a repeated type. */
3004 if (work->previous_argument)
3005 string_clear (work->previous_argument);
3006 else
3007 {
3008 work->previous_argument = (string*) xmalloc (sizeof (string));
3009 string_init (work->previous_argument);
3010 }
3011
3012 if (!do_type (work, mangled, work->previous_argument))
3013 return 0;
3014
3015 string_appends (result, work->previous_argument);
3016
3017 remember_type (work, start, *mangled - start);
3018 return 1;
3019 }
3020
3021 static void
3022 remember_type (work, start, len)
3023 struct work_stuff *work;
3024 const char *start;
3025 int len;
3026 {
3027 char *tem;
3028
3029 if (work->forgetting_types)
3030 return;
3031
3032 if (work -> ntypes >= work -> typevec_size)
3033 {
3034 if (work -> typevec_size == 0)
3035 {
3036 work -> typevec_size = 3;
3037 work -> typevec
3038 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3039 }
3040 else
3041 {
3042 work -> typevec_size *= 2;
3043 work -> typevec
3044 = (char **) xrealloc ((char *)work -> typevec,
3045 sizeof (char *) * work -> typevec_size);
3046 }
3047 }
3048 tem = xmalloc (len + 1);
3049 memcpy (tem, start, len);
3050 tem[len] = '\0';
3051 work -> typevec[work -> ntypes++] = tem;
3052 }
3053
3054
3055 /* Remember a K type class qualifier. */
3056 static void
3057 remember_Ktype (work, start, len)
3058 struct work_stuff *work;
3059 const char *start;
3060 int len;
3061 {
3062 char *tem;
3063
3064 if (work -> numk >= work -> ksize)
3065 {
3066 if (work -> ksize == 0)
3067 {
3068 work -> ksize = 5;
3069 work -> ktypevec
3070 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3071 }
3072 else
3073 {
3074 work -> ksize *= 2;
3075 work -> ktypevec
3076 = (char **) xrealloc ((char *)work -> ktypevec,
3077 sizeof (char *) * work -> ksize);
3078 }
3079 }
3080 tem = xmalloc (len + 1);
3081 memcpy (tem, start, len);
3082 tem[len] = '\0';
3083 work -> ktypevec[work -> numk++] = tem;
3084 }
3085
3086 /* Register a B code, and get an index for it. B codes are registered
3087 as they are seen, rather than as they are completed, so map<temp<char> >
3088 registers map<temp<char> > as B0, and temp<char> as B1 */
3089
3090 static int
3091 register_Btype (work)
3092 struct work_stuff *work;
3093 {
3094 int ret;
3095
3096 if (work -> numb >= work -> bsize)
3097 {
3098 if (work -> bsize == 0)
3099 {
3100 work -> bsize = 5;
3101 work -> btypevec
3102 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3103 }
3104 else
3105 {
3106 work -> bsize *= 2;
3107 work -> btypevec
3108 = (char **) xrealloc ((char *)work -> btypevec,
3109 sizeof (char *) * work -> bsize);
3110 }
3111 }
3112 ret = work -> numb++;
3113 work -> btypevec[ret] = NULL;
3114 return(ret);
3115 }
3116
3117 /* Store a value into a previously registered B code type. */
3118
3119 static void
3120 remember_Btype (work, start, len, index)
3121 struct work_stuff *work;
3122 const char *start;
3123 int len, index;
3124 {
3125 char *tem;
3126
3127 tem = xmalloc (len + 1);
3128 memcpy (tem, start, len);
3129 tem[len] = '\0';
3130 work -> btypevec[index] = tem;
3131 }
3132
3133 /* Lose all the info related to B and K type codes. */
3134 static void
3135 forget_B_and_K_types (work)
3136 struct work_stuff *work;
3137 {
3138 int i;
3139
3140 while (work -> numk > 0)
3141 {
3142 i = --(work -> numk);
3143 if (work -> ktypevec[i] != NULL)
3144 {
3145 free (work -> ktypevec[i]);
3146 work -> ktypevec[i] = NULL;
3147 }
3148 }
3149
3150 while (work -> numb > 0)
3151 {
3152 i = --(work -> numb);
3153 if (work -> btypevec[i] != NULL)
3154 {
3155 free (work -> btypevec[i]);
3156 work -> btypevec[i] = NULL;
3157 }
3158 }
3159 }
3160 /* Forget the remembered types, but not the type vector itself. */
3161
3162 static void
3163 forget_types (work)
3164 struct work_stuff *work;
3165 {
3166 int i;
3167
3168 while (work -> ntypes > 0)
3169 {
3170 i = --(work -> ntypes);
3171 if (work -> typevec[i] != NULL)
3172 {
3173 free (work -> typevec[i]);
3174 work -> typevec[i] = NULL;
3175 }
3176 }
3177 }
3178
3179 /* Process the argument list part of the signature, after any class spec
3180 has been consumed, as well as the first 'F' character (if any). For
3181 example:
3182
3183 "__als__3fooRT0" => process "RT0"
3184 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3185
3186 DECLP must be already initialised, usually non-empty. It won't be freed
3187 on failure.
3188
3189 Note that g++ differs significantly from ARM and lucid style mangling
3190 with regards to references to previously seen types. For example, given
3191 the source fragment:
3192
3193 class foo {
3194 public:
3195 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3196 };
3197
3198 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3199 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3200
3201 g++ produces the names:
3202
3203 __3fooiRT0iT2iT2
3204 foo__FiR3fooiT1iT1
3205
3206 while lcc (and presumably other ARM style compilers as well) produces:
3207
3208 foo__FiR3fooT1T2T1T2
3209 __ct__3fooFiR3fooT1T2T1T2
3210
3211 Note that g++ bases its type numbers starting at zero and counts all
3212 previously seen types, while lucid/ARM bases its type numbers starting
3213 at one and only considers types after it has seen the 'F' character
3214 indicating the start of the function args. For lucid/ARM style, we
3215 account for this difference by discarding any previously seen types when
3216 we see the 'F' character, and subtracting one from the type number
3217 reference.
3218
3219 */
3220
3221 static int
3222 demangle_args (work, mangled, declp)
3223 struct work_stuff *work;
3224 const char **mangled;
3225 string *declp;
3226 {
3227 string arg;
3228 int need_comma = 0;
3229 int r;
3230 int t;
3231 const char *tem;
3232 char temptype;
3233
3234 if (PRINT_ARG_TYPES)
3235 {
3236 string_append (declp, "(");
3237 if (**mangled == '\0')
3238 {
3239 string_append (declp, "void");
3240 }
3241 }
3242
3243 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3244 || work->nrepeats > 0)
3245 {
3246 if ((**mangled == 'N') || (**mangled == 'T'))
3247 {
3248 temptype = *(*mangled)++;
3249
3250 if (temptype == 'N')
3251 {
3252 if (!get_count (mangled, &r))
3253 {
3254 return (0);
3255 }
3256 }
3257 else
3258 {
3259 r = 1;
3260 }
3261 if (ARM_DEMANGLING && work -> ntypes >= 10)
3262 {
3263 /* If we have 10 or more types we might have more than a 1 digit
3264 index so we'll have to consume the whole count here. This
3265 will lose if the next thing is a type name preceded by a
3266 count but it's impossible to demangle that case properly
3267 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3268 Pc, ...)" or "(..., type12, char *, ...)" */
3269 if ((t = consume_count(mangled)) == 0)
3270 {
3271 return (0);
3272 }
3273 }
3274 else
3275 {
3276 if (!get_count (mangled, &t))
3277 {
3278 return (0);
3279 }
3280 }
3281 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3282 {
3283 t--;
3284 }
3285 /* Validate the type index. Protect against illegal indices from
3286 malformed type strings. */
3287 if ((t < 0) || (t >= work -> ntypes))
3288 {
3289 return (0);
3290 }
3291 while (work->nrepeats > 0 || --r >= 0)
3292 {
3293 tem = work -> typevec[t];
3294 if (need_comma && PRINT_ARG_TYPES)
3295 {
3296 string_append (declp, ", ");
3297 }
3298 if (!do_arg (work, &tem, &arg))
3299 {
3300 return (0);
3301 }
3302 if (PRINT_ARG_TYPES)
3303 {
3304 string_appends (declp, &arg);
3305 }
3306 string_delete (&arg);
3307 need_comma = 1;
3308 }
3309 }
3310 else
3311 {
3312 if (need_comma && PRINT_ARG_TYPES)
3313 string_append (declp, ", ");
3314 if (!do_arg (work, mangled, &arg))
3315 return (0);
3316 if (PRINT_ARG_TYPES)
3317 string_appends (declp, &arg);
3318 string_delete (&arg);
3319 need_comma = 1;
3320 }
3321 }
3322
3323 if (**mangled == 'e')
3324 {
3325 (*mangled)++;
3326 if (PRINT_ARG_TYPES)
3327 {
3328 if (need_comma)
3329 {
3330 string_append (declp, ",");
3331 }
3332 string_append (declp, "...");
3333 }
3334 }
3335
3336 if (PRINT_ARG_TYPES)
3337 {
3338 string_append (declp, ")");
3339 }
3340 return (1);
3341 }
3342
3343 /* Like demangle_args, but for demangling the argument lists of function
3344 and method pointers or references, not top-level declarations. */
3345
3346 static int
3347 demangle_nested_args (work, mangled, declp)
3348 struct work_stuff *work;
3349 const char **mangled;
3350 string *declp;
3351 {
3352 string* saved_previous_argument;
3353 int result;
3354 int saved_nrepeats;
3355
3356 /* The G++ name-mangling algorithm does not remember types on nested
3357 argument lists, unless -fsquangling is used, and in that case the
3358 type vector updated by remember_type is not used. So, we turn
3359 off remembering of types here. */
3360 ++work->forgetting_types;
3361
3362 /* For the repeat codes used with -fsquangling, we must keep track of
3363 the last argument. */
3364 saved_previous_argument = work->previous_argument;
3365 saved_nrepeats = work->nrepeats;
3366 work->previous_argument = 0;
3367 work->nrepeats = 0;
3368
3369 /* Actually demangle the arguments. */
3370 result = demangle_args (work, mangled, declp);
3371
3372 /* Restore the previous_argument field. */
3373 if (work->previous_argument)
3374 string_delete (work->previous_argument);
3375 work->previous_argument = saved_previous_argument;
3376 work->nrepeats = saved_nrepeats;
3377
3378 return result;
3379 }
3380
3381 static void
3382 demangle_function_name (work, mangled, declp, scan)
3383 struct work_stuff *work;
3384 const char **mangled;
3385 string *declp;
3386 const char *scan;
3387 {
3388 size_t i;
3389 string type;
3390 const char *tem;
3391
3392 string_appendn (declp, (*mangled), scan - (*mangled));
3393 string_need (declp, 1);
3394 *(declp -> p) = '\0';
3395
3396 /* Consume the function name, including the "__" separating the name
3397 from the signature. We are guaranteed that SCAN points to the
3398 separator. */
3399
3400 (*mangled) = scan + 2;
3401
3402 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3403 {
3404
3405 /* See if we have an ARM style constructor or destructor operator.
3406 If so, then just record it, clear the decl, and return.
3407 We can't build the actual constructor/destructor decl until later,
3408 when we recover the class name from the signature. */
3409
3410 if (strcmp (declp -> b, "__ct") == 0)
3411 {
3412 work -> constructor += 1;
3413 string_clear (declp);
3414 return;
3415 }
3416 else if (strcmp (declp -> b, "__dt") == 0)
3417 {
3418 work -> destructor += 1;
3419 string_clear (declp);
3420 return;
3421 }
3422 }
3423
3424 if (declp->p - declp->b >= 3
3425 && declp->b[0] == 'o'
3426 && declp->b[1] == 'p'
3427 && strchr (cplus_markers, declp->b[2]) != NULL)
3428 {
3429 /* see if it's an assignment expression */
3430 if (declp->p - declp->b >= 10 /* op$assign_ */
3431 && memcmp (declp->b + 3, "assign_", 7) == 0)
3432 {
3433 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3434 {
3435 int len = declp->p - declp->b - 10;
3436 if ((int) strlen (optable[i].in) == len
3437 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3438 {
3439 string_clear (declp);
3440 string_append (declp, "operator");
3441 string_append (declp, optable[i].out);
3442 string_append (declp, "=");
3443 break;
3444 }
3445 }
3446 }
3447 else
3448 {
3449 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3450 {
3451 int len = declp->p - declp->b - 3;
3452 if ((int) strlen (optable[i].in) == len
3453 && memcmp (optable[i].in, declp->b + 3, len) == 0)
3454 {
3455 string_clear (declp);
3456 string_append (declp, "operator");
3457 string_append (declp, optable[i].out);
3458 break;
3459 }
3460 }
3461 }
3462 }
3463 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3464 && strchr (cplus_markers, declp->b[4]) != NULL)
3465 {
3466 /* type conversion operator */
3467 tem = declp->b + 5;
3468 if (do_type (work, &tem, &type))
3469 {
3470 string_clear (declp);
3471 string_append (declp, "operator ");
3472 string_appends (declp, &type);
3473 string_delete (&type);
3474 }
3475 }
3476 else if (declp->b[0] == '_' && declp->b[1] == '_'
3477 && declp->b[2] == 'o' && declp->b[3] == 'p')
3478 {
3479 /* ANSI. */
3480 /* type conversion operator. */
3481 tem = declp->b + 4;
3482 if (do_type (work, &tem, &type))
3483 {
3484 string_clear (declp);
3485 string_append (declp, "operator ");
3486 string_appends (declp, &type);
3487 string_delete (&type);
3488 }
3489 }
3490 else if (declp->b[0] == '_' && declp->b[1] == '_'
3491 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3492 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3493 {
3494 if (declp->b[4] == '\0')
3495 {
3496 /* Operator. */
3497 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3498 {
3499 if (strlen (optable[i].in) == 2
3500 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3501 {
3502 string_clear (declp);
3503 string_append (declp, "operator");
3504 string_append (declp, optable[i].out);
3505 break;
3506 }
3507 }
3508 }
3509 else
3510 {
3511 if (declp->b[2] == 'a' && declp->b[5] == '\0')
3512 {
3513 /* Assignment. */
3514 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3515 {
3516 if (strlen (optable[i].in) == 3
3517 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3518 {
3519 string_clear (declp);
3520 string_append (declp, "operator");
3521 string_append (declp, optable[i].out);
3522 break;
3523 }
3524 }
3525 }
3526 }
3527 }
3528 }
3529
3530 /* a mini string-handling package */
3531
3532 static void
3533 string_need (s, n)
3534 string *s;
3535 int n;
3536 {
3537 int tem;
3538
3539 if (s->b == NULL)
3540 {
3541 if (n < 32)
3542 {
3543 n = 32;
3544 }
3545 s->p = s->b = xmalloc (n);
3546 s->e = s->b + n;
3547 }
3548 else if (s->e - s->p < n)
3549 {
3550 tem = s->p - s->b;
3551 n += tem;
3552 n *= 2;
3553 s->b = xrealloc (s->b, n);
3554 s->p = s->b + tem;
3555 s->e = s->b + n;
3556 }
3557 }
3558
3559 static void
3560 string_delete (s)
3561 string *s;
3562 {
3563 if (s->b != NULL)
3564 {
3565 free (s->b);
3566 s->b = s->e = s->p = NULL;
3567 }
3568 }
3569
3570 static void
3571 string_init (s)
3572 string *s;
3573 {
3574 s->b = s->p = s->e = NULL;
3575 }
3576
3577 static void
3578 string_clear (s)
3579 string *s;
3580 {
3581 s->p = s->b;
3582 }
3583
3584 #if 0
3585
3586 static int
3587 string_empty (s)
3588 string *s;
3589 {
3590 return (s->b == s->p);
3591 }
3592
3593 #endif
3594
3595 static void
3596 string_append (p, s)
3597 string *p;
3598 const char *s;
3599 {
3600 int n;
3601 if (s == NULL || *s == '\0')
3602 return;
3603 n = strlen (s);
3604 string_need (p, n);
3605 memcpy (p->p, s, n);
3606 p->p += n;
3607 }
3608
3609 static void
3610 string_appends (p, s)
3611 string *p, *s;
3612 {
3613 int n;
3614
3615 if (s->b != s->p)
3616 {
3617 n = s->p - s->b;
3618 string_need (p, n);
3619 memcpy (p->p, s->b, n);
3620 p->p += n;
3621 }
3622 }
3623
3624 static void
3625 string_appendn (p, s, n)
3626 string *p;
3627 const char *s;
3628 int n;
3629 {
3630 if (n != 0)
3631 {
3632 string_need (p, n);
3633 memcpy (p->p, s, n);
3634 p->p += n;
3635 }
3636 }
3637
3638 static void
3639 string_prepend (p, s)
3640 string *p;
3641 const char *s;
3642 {
3643 if (s != NULL && *s != '\0')
3644 {
3645 string_prependn (p, s, strlen (s));
3646 }
3647 }
3648
3649 static void
3650 string_prepends (p, s)
3651 string *p, *s;
3652 {
3653 if (s->b != s->p)
3654 {
3655 string_prependn (p, s->b, s->p - s->b);
3656 }
3657 }
3658
3659 static void
3660 string_prependn (p, s, n)
3661 string *p;
3662 const char *s;
3663 int n;
3664 {
3665 char *q;
3666
3667 if (n != 0)
3668 {
3669 string_need (p, n);
3670 for (q = p->p - 1; q >= p->b; q--)
3671 {
3672 q[n] = q[0];
3673 }
3674 memcpy (p->b, s, n);
3675 p->p += n;
3676 }
3677 }
3678
3679 /* To generate a standalone demangler program for testing purposes,
3680 just compile and link this file with -DMAIN and libiberty.a. When
3681 run, it demangles each command line arg, or each stdin string, and
3682 prints the result on stdout. */
3683
3684 #ifdef MAIN
3685
3686 #include "getopt.h"
3687
3688 static char *program_name;
3689 static char *program_version = VERSION;
3690 static int flags = DMGL_PARAMS | DMGL_ANSI;
3691
3692 static void demangle_it PARAMS ((char *));
3693 static void usage PARAMS ((FILE *, int));
3694 static void fatal PARAMS ((char *));
3695
3696 static void
3697 demangle_it (mangled_name)
3698 char *mangled_name;
3699 {
3700 char *result;
3701
3702 result = cplus_demangle (mangled_name, flags);
3703 if (result == NULL)
3704 {
3705 printf ("%s\n", mangled_name);
3706 }
3707 else
3708 {
3709 printf ("%s\n", result);
3710 free (result);
3711 }
3712 }
3713
3714 static void
3715 usage (stream, status)
3716 FILE *stream;
3717 int status;
3718 {
3719 fprintf (stream, "\
3720 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3721 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3722 [--help] [--version] [arg...]\n",
3723 program_name);
3724 exit (status);
3725 }
3726
3727 #define MBUF_SIZE 32767
3728 char mbuffer[MBUF_SIZE];
3729
3730 /* Defined in the automatically-generated underscore.c. */
3731 extern int prepends_underscore;
3732
3733 int strip_underscore = 0;
3734
3735 static struct option long_options[] = {
3736 {"strip-underscores", no_argument, 0, '_'},
3737 {"format", required_argument, 0, 's'},
3738 {"help", no_argument, 0, 'h'},
3739 {"no-strip-underscores", no_argument, 0, 'n'},
3740 {"version", no_argument, 0, 'v'},
3741 {0, no_argument, 0, 0}
3742 };
3743
3744 /* More 'friendly' abort that prints the line and file.
3745 config.h can #define abort fancy_abort if you like that sort of thing. */
3746
3747 void
3748 fancy_abort ()
3749 {
3750 fatal ("Internal gcc abort.");
3751 }
3752
3753 int
3754 main (argc, argv)
3755 int argc;
3756 char **argv;
3757 {
3758 char *result;
3759 int c;
3760
3761 program_name = argv[0];
3762
3763 strip_underscore = prepends_underscore;
3764
3765 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3766 {
3767 switch (c)
3768 {
3769 case '?':
3770 usage (stderr, 1);
3771 break;
3772 case 'h':
3773 usage (stdout, 0);
3774 case 'n':
3775 strip_underscore = 0;
3776 break;
3777 case 'v':
3778 printf ("GNU %s version %s\n", program_name, program_version);
3779 exit (0);
3780 case '_':
3781 strip_underscore = 1;
3782 break;
3783 case 's':
3784 if (strcmp (optarg, "gnu") == 0)
3785 {
3786 current_demangling_style = gnu_demangling;
3787 }
3788 else if (strcmp (optarg, "lucid") == 0)
3789 {
3790 current_demangling_style = lucid_demangling;
3791 }
3792 else if (strcmp (optarg, "arm") == 0)
3793 {
3794 current_demangling_style = arm_demangling;
3795 }
3796 else
3797 {
3798 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3799 program_name, optarg);
3800 exit (1);
3801 }
3802 break;
3803 }
3804 }
3805
3806 if (optind < argc)
3807 {
3808 for ( ; optind < argc; optind++)
3809 {
3810 demangle_it (argv[optind]);
3811 }
3812 }
3813 else
3814 {
3815 for (;;)
3816 {
3817 int i = 0;
3818 c = getchar ();
3819 /* Try to read a label. */
3820 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3821 {
3822 if (i >= MBUF_SIZE-1)
3823 break;
3824 mbuffer[i++] = c;
3825 c = getchar ();
3826 }
3827 if (i > 0)
3828 {
3829 int skip_first = 0;
3830
3831 if (mbuffer[0] == '.')
3832 ++skip_first;
3833 if (strip_underscore && mbuffer[skip_first] == '_')
3834 ++skip_first;
3835
3836 if (skip_first > i)
3837 skip_first = i;
3838
3839 mbuffer[i] = 0;
3840
3841 result = cplus_demangle (mbuffer + skip_first, flags);
3842 if (result)
3843 {
3844 if (mbuffer[0] == '.')
3845 putc ('.', stdout);
3846 fputs (result, stdout);
3847 free (result);
3848 }
3849 else
3850 fputs (mbuffer, stdout);
3851
3852 fflush (stdout);
3853 }
3854 if (c == EOF)
3855 break;
3856 putchar (c);
3857 }
3858 }
3859
3860 exit (0);
3861 }
3862
3863 static void
3864 fatal (str)
3865 char *str;
3866 {
3867 fprintf (stderr, "%s: %s\n", program_name, str);
3868 exit (1);
3869 }
3870
3871 char *
3872 xmalloc (size)
3873 unsigned size;
3874 {
3875 register char *value = (char *) malloc (size);
3876 if (value == 0)
3877 fatal ("virtual memory exhausted");
3878 return value;
3879 }
3880
3881 char *
3882 xrealloc (ptr, size)
3883 char *ptr;
3884 unsigned size;
3885 {
3886 register char *value = (char *) realloc (ptr, size);
3887 if (value == 0)
3888 fatal ("virtual memory exhausted");
3889 return value;
3890 }
3891 #endif /* main */