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