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