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