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