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