OSDN Git Service

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