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