OSDN Git Service

* testsuite/demangle-expected: Add test case for infinite loop in
[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             {
2418               const char* old_args = args;
2419               if (!do_type (work, &args, &arg))
2420                 goto cfront_template_args_done;
2421
2422               /* Fail if we didn't make any progress: prevent infinite loop. */
2423               if (args == old_args)
2424                 return;
2425             }
2426           }
2427         string_appends (declp, &arg);
2428         string_append (declp, ",");
2429       }
2430     cfront_template_args_done:
2431       string_delete (&arg);
2432       if (args >= e)
2433         --declp->p; /* remove extra comma */
2434       string_append (declp, ">");
2435     }
2436   else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2437            && (*mangled)[9] == 'N'
2438            && (*mangled)[8] == (*mangled)[10]
2439            && strchr (cplus_markers, (*mangled)[8]))
2440     {
2441       /* A member of the anonymous namespace.  */
2442       string_append (declp, "{anonymous}");
2443     }
2444   else
2445     {
2446       if (work->temp_start == -1) /* non-recursive call only */
2447         work->temp_start = 0;     /* disable in recursive calls */
2448       string_appendn (declp, *mangled, n);
2449     }
2450   *mangled += n;
2451 }
2452
2453 /* Extract a class name, possibly a template with arguments, from the
2454    mangled string; qualifiers, local class indicators, etc. have
2455    already been dealt with */
2456
2457 static int
2458 demangle_class_name (work, mangled, declp)
2459      struct work_stuff *work;
2460      const char **mangled;
2461      string *declp;
2462 {
2463   int n;
2464   int success = 0;
2465
2466   n = consume_count (mangled);
2467   if (n == -1)
2468     return 0;
2469   if ((int) strlen (*mangled) >= n)
2470     {
2471       demangle_arm_hp_template (work, mangled, n, declp);
2472       success = 1;
2473     }
2474
2475   return (success);
2476 }
2477
2478 /*
2479
2480 LOCAL FUNCTION
2481
2482         demangle_class -- demangle a mangled class sequence
2483
2484 SYNOPSIS
2485
2486         static int
2487         demangle_class (struct work_stuff *work, const char **mangled,
2488                         strint *declp)
2489
2490 DESCRIPTION
2491
2492         DECLP points to the buffer into which demangling is being done.
2493
2494         *MANGLED points to the current token to be demangled.  On input,
2495         it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2496         On exit, it points to the next token after the mangled class on
2497         success, or the first unconsumed token on failure.
2498
2499         If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2500         we are demangling a constructor or destructor.  In this case
2501         we prepend "class::class" or "class::~class" to DECLP.
2502
2503         Otherwise, we prepend "class::" to the current DECLP.
2504
2505         Reset the constructor/destructor flags once they have been
2506         "consumed".  This allows demangle_class to be called later during
2507         the same demangling, to do normal class demangling.
2508
2509         Returns 1 if demangling is successful, 0 otherwise.
2510
2511 */
2512
2513 static int
2514 demangle_class (work, mangled, declp)
2515      struct work_stuff *work;
2516      const char **mangled;
2517      string *declp;
2518 {
2519   int success = 0;
2520   int btype;
2521   string class_name;
2522   char *save_class_name_end = 0;
2523
2524   string_init (&class_name);
2525   btype = register_Btype (work);
2526   if (demangle_class_name (work, mangled, &class_name))
2527     {
2528       save_class_name_end = class_name.p;
2529       if ((work->constructor & 1) || (work->destructor & 1))
2530         {
2531           /* adjust so we don't include template args */
2532           if (work->temp_start && (work->temp_start != -1))
2533             {
2534               class_name.p = class_name.b + work->temp_start;
2535             }
2536           string_prepends (declp, &class_name);
2537           if (work -> destructor & 1)
2538             {
2539               string_prepend (declp, "~");
2540               work -> destructor -= 1;
2541             }
2542           else
2543             {
2544               work -> constructor -= 1;
2545             }
2546         }
2547       class_name.p = save_class_name_end;
2548       remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2549       remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2550       string_prepend (declp, SCOPE_STRING (work));
2551       string_prepends (declp, &class_name);
2552       success = 1;
2553     }
2554   string_delete (&class_name);
2555   return (success);
2556 }
2557
2558
2559 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2560    the rightmost guess.
2561
2562    Find the correct "__"-sequence where the function name ends and the
2563    signature starts, which is ambiguous with GNU mangling.
2564    Call demangle_signature here, so we can make sure we found the right
2565    one; *mangled will be consumed so caller will not make further calls to
2566    demangle_signature.  */
2567
2568 static int
2569 iterate_demangle_function (work, mangled, declp, scan)
2570      struct work_stuff *work;
2571      const char **mangled;
2572      string *declp;
2573      const char *scan;
2574 {
2575   const char *mangle_init = *mangled;
2576   int success = 0;
2577   string decl_init;
2578   struct work_stuff work_init;
2579
2580   if (*(scan + 2) == '\0')
2581     return 0;
2582
2583   /* Do not iterate for some demangling modes, or if there's only one
2584      "__"-sequence.  This is the normal case.  */
2585   if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2586       || strstr (scan + 2, "__") == NULL)
2587     {
2588       demangle_function_name (work, mangled, declp, scan);
2589       return 1;
2590     }
2591
2592   /* Save state so we can restart if the guess at the correct "__" was
2593      wrong.  */
2594   string_init (&decl_init);
2595   string_appends (&decl_init, declp);
2596   memset (&work_init, 0, sizeof work_init);
2597   work_stuff_copy_to_from (&work_init, work);
2598
2599   /* Iterate over occurrences of __, allowing names and types to have a
2600      "__" sequence in them.  We must start with the first (not the last)
2601      occurrence, since "__" most often occur between independent mangled
2602      parts, hence starting at the last occurence inside a signature
2603      might get us a "successful" demangling of the signature.  */
2604
2605   while (scan[2])
2606     {
2607       demangle_function_name (work, mangled, declp, scan);
2608       success = demangle_signature (work, mangled, declp);
2609       if (success)
2610         break;
2611
2612       /* Reset demangle state for the next round.  */
2613       *mangled = mangle_init;
2614       string_clear (declp);
2615       string_appends (declp, &decl_init);
2616       work_stuff_copy_to_from (work, &work_init);
2617
2618       /* Leave this underscore-sequence.  */
2619       scan += 2;
2620
2621       /* Scan for the next "__" sequence.  */
2622       while (*scan && (scan[0] != '_' || scan[1] != '_'))
2623         scan++;
2624
2625       /* Move to last "__" in this sequence.  */
2626       while (*scan && *scan == '_')
2627         scan++;
2628       scan -= 2;
2629     }
2630
2631   /* Delete saved state.  */
2632   delete_work_stuff (&work_init);
2633   string_delete (&decl_init);
2634
2635   return success;
2636 }
2637
2638 /*
2639
2640 LOCAL FUNCTION
2641
2642         demangle_prefix -- consume the mangled name prefix and find signature
2643
2644 SYNOPSIS
2645
2646         static int
2647         demangle_prefix (struct work_stuff *work, const char **mangled,
2648                          string *declp);
2649
2650 DESCRIPTION
2651
2652         Consume and demangle the prefix of the mangled name.
2653         While processing the function name root, arrange to call
2654         demangle_signature if the root is ambiguous.
2655
2656         DECLP points to the string buffer into which demangled output is
2657         placed.  On entry, the buffer is empty.  On exit it contains
2658         the root function name, the demangled operator name, or in some
2659         special cases either nothing or the completely demangled result.
2660
2661         MANGLED points to the current pointer into the mangled name.  As each
2662         token of the mangled name is consumed, it is updated.  Upon entry
2663         the current mangled name pointer points to the first character of
2664         the mangled name.  Upon exit, it should point to the first character
2665         of the signature if demangling was successful, or to the first
2666         unconsumed character if demangling of the prefix was unsuccessful.
2667
2668         Returns 1 on success, 0 otherwise.
2669  */
2670
2671 static int
2672 demangle_prefix (work, mangled, declp)
2673      struct work_stuff *work;
2674      const char **mangled;
2675      string *declp;
2676 {
2677   int success = 1;
2678   const char *scan;
2679   int i;
2680
2681   if (strlen(*mangled) > 6
2682       && (strncmp(*mangled, "_imp__", 6) == 0
2683           || strncmp(*mangled, "__imp_", 6) == 0))
2684     {
2685       /* it's a symbol imported from a PE dynamic library. Check for both
2686          new style prefix _imp__ and legacy __imp_ used by older versions
2687          of dlltool. */
2688       (*mangled) += 6;
2689       work->dllimported = 1;
2690     }
2691   else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2692     {
2693       char *marker = strchr (cplus_markers, (*mangled)[8]);
2694       if (marker != NULL && *marker == (*mangled)[10])
2695         {
2696           if ((*mangled)[9] == 'D')
2697             {
2698               /* it's a GNU global destructor to be executed at program exit */
2699               (*mangled) += 11;
2700               work->destructor = 2;
2701               if (gnu_special (work, mangled, declp))
2702                 return success;
2703             }
2704           else if ((*mangled)[9] == 'I')
2705             {
2706               /* it's a GNU global constructor to be executed at program init */
2707               (*mangled) += 11;
2708               work->constructor = 2;
2709               if (gnu_special (work, mangled, declp))
2710                 return success;
2711             }
2712         }
2713     }
2714   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2715     {
2716       /* it's a ARM global destructor to be executed at program exit */
2717       (*mangled) += 7;
2718       work->destructor = 2;
2719     }
2720   else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2721     {
2722       /* it's a ARM global constructor to be executed at program initial */
2723       (*mangled) += 7;
2724       work->constructor = 2;
2725     }
2726
2727   /*  This block of code is a reduction in strength time optimization
2728       of:
2729       scan = strstr (*mangled, "__"); */
2730
2731   {
2732     scan = *mangled;
2733
2734     do {
2735       scan = strchr (scan, '_');
2736     } while (scan != NULL && *++scan != '_');
2737
2738     if (scan != NULL) --scan;
2739   }
2740
2741   if (scan != NULL)
2742     {
2743       /* We found a sequence of two or more '_', ensure that we start at
2744          the last pair in the sequence.  */
2745       i = strspn (scan, "_");
2746       if (i > 2)
2747         {
2748           scan += (i - 2);
2749         }
2750     }
2751
2752   if (scan == NULL)
2753     {
2754       success = 0;
2755     }
2756   else if (work -> static_type)
2757     {
2758       if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2759         {
2760           success = 0;
2761         }
2762     }
2763   else if ((scan == *mangled)
2764            && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2765                || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2766     {
2767       /* The ARM says nothing about the mangling of local variables.
2768          But cfront mangles local variables by prepending __<nesting_level>
2769          to them. As an extension to ARM demangling we handle this case.  */
2770       if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2771           && ISDIGIT ((unsigned char)scan[2]))
2772         {
2773           *mangled = scan + 2;
2774           consume_count (mangled);
2775           string_append (declp, *mangled);
2776           *mangled += strlen (*mangled);
2777           success = 1;
2778         }
2779       else
2780         {
2781           /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
2782              names like __Q2_3foo3bar for nested type names.  So don't accept
2783              this style of constructor for cfront demangling.  A GNU
2784              style member-template constructor starts with 'H'. */
2785           if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2786             work -> constructor += 1;
2787           *mangled = scan + 2;
2788         }
2789     }
2790   else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2791     {
2792       /* Cfront-style parameterized type.  Handled later as a signature. */
2793       success = 1;
2794
2795       /* ARM template? */
2796       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2797     }
2798   else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2799                               || (scan[2] == 'p' && scan[3] == 's')
2800                               || (scan[2] == 'p' && scan[3] == 't')))
2801     {
2802       /* EDG-style parameterized type.  Handled later as a signature. */
2803       success = 1;
2804
2805       /* EDG template? */
2806       demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2807     }
2808   else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2809            && (scan[2] != 't'))
2810     {
2811       /* Mangled name starts with "__".  Skip over any leading '_' characters,
2812          then find the next "__" that separates the prefix from the signature.
2813          */
2814       if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2815           || (arm_special (mangled, declp) == 0))
2816         {
2817           while (*scan == '_')
2818             {
2819               scan++;
2820             }
2821           if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2822             {
2823               /* No separator (I.E. "__not_mangled"), or empty signature
2824                  (I.E. "__not_mangled_either__") */
2825               success = 0;
2826             }
2827           else
2828             return iterate_demangle_function (work, mangled, declp, scan);
2829         }
2830     }
2831   else if (*(scan + 2) != '\0')
2832     {
2833       /* Mangled name does not start with "__" but does have one somewhere
2834          in there with non empty stuff after it.  Looks like a global
2835          function name.  Iterate over all "__":s until the right
2836          one is found.  */
2837       return iterate_demangle_function (work, mangled, declp, scan);
2838     }
2839   else
2840     {
2841       /* Doesn't look like a mangled name */
2842       success = 0;
2843     }
2844
2845   if (!success && (work->constructor == 2 || work->destructor == 2))
2846     {
2847       string_append (declp, *mangled);
2848       *mangled += strlen (*mangled);
2849       success = 1;
2850     }
2851   return (success);
2852 }
2853
2854 /*
2855
2856 LOCAL FUNCTION
2857
2858         gnu_special -- special handling of gnu mangled strings
2859
2860 SYNOPSIS
2861
2862         static int
2863         gnu_special (struct work_stuff *work, const char **mangled,
2864                      string *declp);
2865
2866
2867 DESCRIPTION
2868
2869         Process some special GNU style mangling forms that don't fit
2870         the normal pattern.  For example:
2871
2872                 _$_3foo         (destructor for class foo)
2873                 _vt$foo         (foo virtual table)
2874                 _vt$foo$bar     (foo::bar virtual table)
2875                 __vt_foo        (foo virtual table, new style with thunks)
2876                 _3foo$varname   (static data member)
2877                 _Q22rs2tu$vw    (static data member)
2878                 __t6vector1Zii  (constructor with template)
2879                 __thunk_4__$_7ostream (virtual function thunk)
2880  */
2881
2882 static int
2883 gnu_special (work, mangled, declp)
2884      struct work_stuff *work;
2885      const char **mangled;
2886      string *declp;
2887 {
2888   int n;
2889   int success = 1;
2890   const char *p;
2891
2892   if ((*mangled)[0] == '_'
2893       && strchr (cplus_markers, (*mangled)[1]) != NULL
2894       && (*mangled)[2] == '_')
2895     {
2896       /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2897       (*mangled) += 3;
2898       work -> destructor += 1;
2899     }
2900   else if ((*mangled)[0] == '_'
2901            && (((*mangled)[1] == '_'
2902                 && (*mangled)[2] == 'v'
2903                 && (*mangled)[3] == 't'
2904                 && (*mangled)[4] == '_')
2905                || ((*mangled)[1] == 'v'
2906                    && (*mangled)[2] == 't'
2907                    && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2908     {
2909       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2910          and create the decl.  Note that we consume the entire mangled
2911          input string, which means that demangle_signature has no work
2912          to do.  */
2913       if ((*mangled)[2] == 'v')
2914         (*mangled) += 5; /* New style, with thunks: "__vt_" */
2915       else
2916         (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2917       while (**mangled != '\0')
2918         {
2919           switch (**mangled)
2920             {
2921             case 'Q':
2922             case 'K':
2923               success = demangle_qualified (work, mangled, declp, 0, 1);
2924               break;
2925             case 't':
2926               success = demangle_template (work, mangled, declp, 0, 1,
2927                                            1);
2928               break;
2929             default:
2930               if (ISDIGIT((unsigned char)*mangled[0]))
2931                 {
2932                   n = consume_count(mangled);
2933                   /* We may be seeing a too-large size, or else a
2934                      ".<digits>" indicating a static local symbol.  In
2935                      any case, declare victory and move on; *don't* try
2936                      to use n to allocate.  */
2937                   if (n > (int) strlen (*mangled))
2938                     {
2939                       success = 1;
2940                       break;
2941                     }
2942                 }
2943               else
2944                 {
2945                   n = strcspn (*mangled, cplus_markers);
2946                 }
2947               string_appendn (declp, *mangled, n);
2948               (*mangled) += n;
2949             }
2950
2951           p = strpbrk (*mangled, cplus_markers);
2952           if (success && ((p == NULL) || (p == *mangled)))
2953             {
2954               if (p != NULL)
2955                 {
2956                   string_append (declp, SCOPE_STRING (work));
2957                   (*mangled)++;
2958                 }
2959             }
2960           else
2961             {
2962               success = 0;
2963               break;
2964             }
2965         }
2966       if (success)
2967         string_append (declp, " virtual table");
2968     }
2969   else if ((*mangled)[0] == '_'
2970            && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2971            && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2972     {
2973       /* static data member, "_3foo$varname" for example */
2974       (*mangled)++;
2975       switch (**mangled)
2976         {
2977         case 'Q':
2978         case 'K':
2979           success = demangle_qualified (work, mangled, declp, 0, 1);
2980           break;
2981         case 't':
2982           success = demangle_template (work, mangled, declp, 0, 1, 1);
2983           break;
2984         default:
2985           n = consume_count (mangled);
2986           if (n < 0 || n > (long) strlen (*mangled))
2987             {
2988               success = 0;
2989               break;
2990             }
2991
2992           if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2993               && (*mangled)[9] == 'N'
2994               && (*mangled)[8] == (*mangled)[10]
2995               && strchr (cplus_markers, (*mangled)[8]))
2996             {
2997               /* A member of the anonymous namespace.  There's information
2998                  about what identifier or filename it was keyed to, but
2999                  it's just there to make the mangled name unique; we just
3000                  step over it.  */
3001               string_append (declp, "{anonymous}");
3002               (*mangled) += n;
3003
3004               /* Now p points to the marker before the N, so we need to
3005                  update it to the first marker after what we consumed.  */
3006               p = strpbrk (*mangled, cplus_markers);
3007               break;
3008             }
3009
3010           string_appendn (declp, *mangled, n);
3011           (*mangled) += n;
3012         }
3013       if (success && (p == *mangled))
3014         {
3015           /* Consumed everything up to the cplus_marker, append the
3016              variable name.  */
3017           (*mangled)++;
3018           string_append (declp, SCOPE_STRING (work));
3019           n = strlen (*mangled);
3020           string_appendn (declp, *mangled, n);
3021           (*mangled) += n;
3022         }
3023       else
3024         {
3025           success = 0;
3026         }
3027     }
3028   else if (strncmp (*mangled, "__thunk_", 8) == 0)
3029     {
3030       int delta;
3031
3032       (*mangled) += 8;
3033       delta = consume_count (mangled);
3034       if (delta == -1)
3035         success = 0;
3036       else
3037         {
3038           char *method = internal_cplus_demangle (work, ++*mangled);
3039
3040           if (method)
3041             {
3042               char buf[50];
3043               sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
3044               string_append (declp, buf);
3045               string_append (declp, method);
3046               free (method);
3047               n = strlen (*mangled);
3048               (*mangled) += n;
3049             }
3050           else
3051             {
3052               success = 0;
3053             }
3054         }
3055     }
3056   else if (strncmp (*mangled, "__t", 3) == 0
3057            && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
3058     {
3059       p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
3060       (*mangled) += 4;
3061       switch (**mangled)
3062         {
3063         case 'Q':
3064         case 'K':
3065           success = demangle_qualified (work, mangled, declp, 0, 1);
3066           break;
3067         case 't':
3068           success = demangle_template (work, mangled, declp, 0, 1, 1);
3069           break;
3070         default:
3071           success = do_type (work, mangled, declp);
3072           break;
3073         }
3074       if (success && **mangled != '\0')
3075         success = 0;
3076       if (success)
3077         string_append (declp, p);
3078     }
3079   else
3080     {
3081       success = 0;
3082     }
3083   return (success);
3084 }
3085
3086 static void
3087 recursively_demangle(work, mangled, result, namelength)
3088      struct work_stuff *work;
3089      const char **mangled;
3090      string *result;
3091      int namelength;
3092 {
3093   char * recurse = (char *)NULL;
3094   char * recurse_dem = (char *)NULL;
3095
3096   recurse = (char *) xmalloc (namelength + 1);
3097   memcpy (recurse, *mangled, namelength);
3098   recurse[namelength] = '\000';
3099
3100   recurse_dem = cplus_demangle (recurse, work->options);
3101
3102   if (recurse_dem)
3103     {
3104       string_append (result, recurse_dem);
3105       free (recurse_dem);
3106     }
3107   else
3108     {
3109       string_appendn (result, *mangled, namelength);
3110     }
3111   free (recurse);
3112   *mangled += namelength;
3113 }
3114
3115 /*
3116
3117 LOCAL FUNCTION
3118
3119         arm_special -- special handling of ARM/lucid mangled strings
3120
3121 SYNOPSIS
3122
3123         static int
3124         arm_special (const char **mangled,
3125                      string *declp);
3126
3127
3128 DESCRIPTION
3129
3130         Process some special ARM style mangling forms that don't fit
3131         the normal pattern.  For example:
3132
3133                 __vtbl__3foo            (foo virtual table)
3134                 __vtbl__3foo__3bar      (bar::foo virtual table)
3135
3136  */
3137
3138 static int
3139 arm_special (mangled, declp)
3140      const char **mangled;
3141      string *declp;
3142 {
3143   int n;
3144   int success = 1;
3145   const char *scan;
3146
3147   if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3148     {
3149       /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3150          and create the decl.  Note that we consume the entire mangled
3151          input string, which means that demangle_signature has no work
3152          to do.  */
3153       scan = *mangled + ARM_VTABLE_STRLEN;
3154       while (*scan != '\0')        /* first check it can be demangled */
3155         {
3156           n = consume_count (&scan);
3157           if (n == -1)
3158             {
3159               return (0);           /* no good */
3160             }
3161           scan += n;
3162           if (scan[0] == '_' && scan[1] == '_')
3163             {
3164               scan += 2;
3165             }
3166         }
3167       (*mangled) += ARM_VTABLE_STRLEN;
3168       while (**mangled != '\0')
3169         {
3170           n = consume_count (mangled);
3171           if (n == -1
3172               || n > (long) strlen (*mangled))
3173             return 0;
3174           string_prependn (declp, *mangled, n);
3175           (*mangled) += n;
3176           if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3177             {
3178               string_prepend (declp, "::");
3179               (*mangled) += 2;
3180             }
3181         }
3182       string_append (declp, " virtual table");
3183     }
3184   else
3185     {
3186       success = 0;
3187     }
3188   return (success);
3189 }
3190
3191 /*
3192
3193 LOCAL FUNCTION
3194
3195         demangle_qualified -- demangle 'Q' qualified name strings
3196
3197 SYNOPSIS
3198
3199         static int
3200         demangle_qualified (struct work_stuff *, const char *mangled,
3201                             string *result, int isfuncname, int append);
3202
3203 DESCRIPTION
3204
3205         Demangle a qualified name, such as "Q25Outer5Inner" which is
3206         the mangled form of "Outer::Inner".  The demangled output is
3207         prepended or appended to the result string according to the
3208         state of the append flag.
3209
3210         If isfuncname is nonzero, then the qualified name we are building
3211         is going to be used as a member function name, so if it is a
3212         constructor or destructor function, append an appropriate
3213         constructor or destructor name.  I.E. for the above example,
3214         the result for use as a constructor is "Outer::Inner::Inner"
3215         and the result for use as a destructor is "Outer::Inner::~Inner".
3216
3217 BUGS
3218
3219         Numeric conversion is ASCII dependent (FIXME).
3220
3221  */
3222
3223 static int
3224 demangle_qualified (work, mangled, result, isfuncname, append)
3225      struct work_stuff *work;
3226      const char **mangled;
3227      string *result;
3228      int isfuncname;
3229      int append;
3230 {
3231   int qualifiers = 0;
3232   int success = 1;
3233   char num[2];
3234   string temp;
3235   string last_name;
3236   int bindex = register_Btype (work);
3237
3238   /* We only make use of ISFUNCNAME if the entity is a constructor or
3239      destructor.  */
3240   isfuncname = (isfuncname
3241                 && ((work->constructor & 1) || (work->destructor & 1)));
3242
3243   string_init (&temp);
3244   string_init (&last_name);
3245
3246   if ((*mangled)[0] == 'K')
3247     {
3248     /* Squangling qualified name reuse */
3249       int idx;
3250       (*mangled)++;
3251       idx = consume_count_with_underscores (mangled);
3252       if (idx == -1 || idx >= work -> numk)
3253         success = 0;
3254       else
3255         string_append (&temp, work -> ktypevec[idx]);
3256     }
3257   else
3258     switch ((*mangled)[1])
3259     {
3260     case '_':
3261       /* GNU mangled name with more than 9 classes.  The count is preceded
3262          by an underscore (to distinguish it from the <= 9 case) and followed
3263          by an underscore.  */
3264       (*mangled)++;
3265       qualifiers = consume_count_with_underscores (mangled);
3266       if (qualifiers == -1)
3267         success = 0;
3268       break;
3269
3270     case '1':
3271     case '2':
3272     case '3':
3273     case '4':
3274     case '5':
3275     case '6':
3276     case '7':
3277     case '8':
3278     case '9':
3279       /* The count is in a single digit.  */
3280       num[0] = (*mangled)[1];
3281       num[1] = '\0';
3282       qualifiers = atoi (num);
3283
3284       /* If there is an underscore after the digit, skip it.  This is
3285          said to be for ARM-qualified names, but the ARM makes no
3286          mention of such an underscore.  Perhaps cfront uses one.  */
3287       if ((*mangled)[2] == '_')
3288         {
3289           (*mangled)++;
3290         }
3291       (*mangled) += 2;
3292       break;
3293
3294     case '0':
3295     default:
3296       success = 0;
3297     }
3298
3299   if (!success)
3300     return success;
3301
3302   /* Pick off the names and collect them in the temp buffer in the order
3303      in which they are found, separated by '::'.  */
3304
3305   while (qualifiers-- > 0)
3306     {
3307       int remember_K = 1;
3308       string_clear (&last_name);
3309
3310       if (*mangled[0] == '_')
3311         (*mangled)++;
3312
3313       if (*mangled[0] == 't')
3314         {
3315           /* Here we always append to TEMP since we will want to use
3316              the template name without the template parameters as a
3317              constructor or destructor name.  The appropriate
3318              (parameter-less) value is returned by demangle_template
3319              in LAST_NAME.  We do not remember the template type here,
3320              in order to match the G++ mangling algorithm.  */
3321           success = demangle_template(work, mangled, &temp,
3322                                       &last_name, 1, 0);
3323           if (!success)
3324             break;
3325         }
3326       else if (*mangled[0] == 'K')
3327         {
3328           int idx;
3329           (*mangled)++;
3330           idx = consume_count_with_underscores (mangled);
3331           if (idx == -1 || idx >= work->numk)
3332             success = 0;
3333           else
3334             string_append (&temp, work->ktypevec[idx]);
3335           remember_K = 0;
3336
3337           if (!success) break;
3338         }
3339       else
3340         {
3341           if (EDG_DEMANGLING)
3342             {
3343               int namelength;
3344               /* Now recursively demangle the qualifier
3345                * This is necessary to deal with templates in
3346                * mangling styles like EDG */
3347               namelength = consume_count (mangled);
3348               if (namelength == -1)
3349                 {
3350                   success = 0;
3351                   break;
3352                 }
3353               recursively_demangle(work, mangled, &temp, namelength);
3354             }
3355           else
3356             {
3357               success = do_type (work, mangled, &last_name);
3358               if (!success)
3359                 break;
3360               string_appends (&temp, &last_name);
3361             }
3362         }
3363
3364       if (remember_K)
3365         remember_Ktype (work, temp.b, LEN_STRING (&temp));
3366
3367       if (qualifiers > 0)
3368         string_append (&temp, SCOPE_STRING (work));
3369     }
3370
3371   remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3372
3373   /* If we are using the result as a function name, we need to append
3374      the appropriate '::' separated constructor or destructor name.
3375      We do this here because this is the most convenient place, where
3376      we already have a pointer to the name and the length of the name.  */
3377
3378   if (isfuncname)
3379     {
3380       string_append (&temp, SCOPE_STRING (work));
3381       if (work -> destructor & 1)
3382         string_append (&temp, "~");
3383       string_appends (&temp, &last_name);
3384     }
3385
3386   /* Now either prepend the temp buffer to the result, or append it,
3387      depending upon the state of the append flag.  */
3388
3389   if (append)
3390     string_appends (result, &temp);
3391   else
3392     {
3393       if (!STRING_EMPTY (result))
3394         string_append (&temp, SCOPE_STRING (work));
3395       string_prepends (result, &temp);
3396     }
3397
3398   string_delete (&last_name);
3399   string_delete (&temp);
3400   return (success);
3401 }
3402
3403 /*
3404
3405 LOCAL FUNCTION
3406
3407         get_count -- convert an ascii count to integer, consuming tokens
3408
3409 SYNOPSIS
3410
3411         static int
3412         get_count (const char **type, int *count)
3413
3414 DESCRIPTION
3415
3416         Assume that *type points at a count in a mangled name; set
3417         *count to its value, and set *type to the next character after
3418         the count.  There are some weird rules in effect here.
3419
3420         If *type does not point at a string of digits, return zero.
3421
3422         If *type points at a string of digits followed by an
3423         underscore, set *count to their value as an integer, advance
3424         *type to point *after the underscore, and return 1.
3425
3426         If *type points at a string of digits not followed by an
3427         underscore, consume only the first digit.  Set *count to its
3428         value as an integer, leave *type pointing after that digit,
3429         and return 1.
3430
3431         The excuse for this odd behavior: in the ARM and HP demangling
3432         styles, a type can be followed by a repeat count of the form
3433         `Nxy', where:
3434
3435         `x' is a single digit specifying how many additional copies
3436             of the type to append to the argument list, and
3437
3438         `y' is one or more digits, specifying the zero-based index of
3439             the first repeated argument in the list.  Yes, as you're
3440             unmangling the name you can figure this out yourself, but
3441             it's there anyway.
3442
3443         So, for example, in `bar__3fooFPiN51', the first argument is a
3444         pointer to an integer (`Pi'), and then the next five arguments
3445         are the same (`N5'), and the first repeat is the function's
3446         second argument (`1').
3447 */
3448
3449 static int
3450 get_count (type, count)
3451      const char **type;
3452      int *count;
3453 {
3454   const char *p;
3455   int n;
3456
3457   if (!ISDIGIT ((unsigned char)**type))
3458     return (0);
3459   else
3460     {
3461       *count = **type - '0';
3462       (*type)++;
3463       if (ISDIGIT ((unsigned char)**type))
3464         {
3465           p = *type;
3466           n = *count;
3467           do
3468             {
3469               n *= 10;
3470               n += *p - '0';
3471               p++;
3472             }
3473           while (ISDIGIT ((unsigned char)*p));
3474           if (*p == '_')
3475             {
3476               *type = p + 1;
3477               *count = n;
3478             }
3479         }
3480     }
3481   return (1);
3482 }
3483
3484 /* RESULT will be initialised here; it will be freed on failure.  The
3485    value returned is really a type_kind_t.  */
3486
3487 static int
3488 do_type (work, mangled, result)
3489      struct work_stuff *work;
3490      const char **mangled;
3491      string *result;
3492 {
3493   int n;
3494   int done;
3495   int success;
3496   string decl;
3497   const char *remembered_type;
3498   int type_quals;
3499   string btype;
3500   type_kind_t tk = tk_none;
3501
3502   string_init (&btype);
3503   string_init (&decl);
3504   string_init (result);
3505
3506   done = 0;
3507   success = 1;
3508   while (success && !done)
3509     {
3510       int member;
3511       switch (**mangled)
3512         {
3513
3514           /* A pointer type */
3515         case 'P':
3516         case 'p':
3517           (*mangled)++;
3518           if (! (work -> options & DMGL_JAVA))
3519             string_prepend (&decl, "*");
3520           if (tk == tk_none)
3521             tk = tk_pointer;
3522           break;
3523
3524           /* A reference type */
3525         case 'R':
3526           (*mangled)++;
3527           string_prepend (&decl, "&");
3528           if (tk == tk_none)
3529             tk = tk_reference;
3530           break;
3531
3532           /* An array */
3533         case 'A':
3534           {
3535             ++(*mangled);
3536             if (!STRING_EMPTY (&decl)
3537                 && (decl.b[0] == '*' || decl.b[0] == '&'))
3538               {
3539                 string_prepend (&decl, "(");
3540                 string_append (&decl, ")");
3541               }
3542             string_append (&decl, "[");
3543             if (**mangled != '_')
3544               success = demangle_template_value_parm (work, mangled, &decl,
3545                                                       tk_integral);
3546             if (**mangled == '_')
3547               ++(*mangled);
3548             string_append (&decl, "]");
3549             break;
3550           }
3551
3552         /* A back reference to a previously seen type */
3553         case 'T':
3554           (*mangled)++;
3555           if (!get_count (mangled, &n) || n >= work -> ntypes)
3556             {
3557               success = 0;
3558             }
3559           else
3560             {
3561               remembered_type = work -> typevec[n];
3562               mangled = &remembered_type;
3563             }
3564           break;
3565
3566           /* A function */
3567         case 'F':
3568           (*mangled)++;
3569             if (!STRING_EMPTY (&decl)
3570                 && (decl.b[0] == '*' || decl.b[0] == '&'))
3571             {
3572               string_prepend (&decl, "(");
3573               string_append (&decl, ")");
3574             }
3575           /* After picking off the function args, we expect to either find the
3576              function return type (preceded by an '_') or the end of the
3577              string.  */
3578           if (!demangle_nested_args (work, mangled, &decl)
3579               || (**mangled != '_' && **mangled != '\0'))
3580             {
3581               success = 0;
3582               break;
3583             }
3584           if (success && (**mangled == '_'))
3585             (*mangled)++;
3586           break;
3587
3588         case 'M':
3589         case 'O':
3590           {
3591             type_quals = TYPE_UNQUALIFIED;
3592
3593             member = **mangled == 'M';
3594             (*mangled)++;
3595
3596             string_append (&decl, ")");
3597
3598             /* We don't need to prepend `::' for a qualified name;
3599                demangle_qualified will do that for us.  */
3600             if (**mangled != 'Q')
3601               string_prepend (&decl, SCOPE_STRING (work));
3602
3603             if (ISDIGIT ((unsigned char)**mangled))
3604               {
3605                 n = consume_count (mangled);
3606                 if (n == -1
3607                     || (int) strlen (*mangled) < n)
3608                   {
3609                     success = 0;
3610                     break;
3611                   }
3612                 string_prependn (&decl, *mangled, n);
3613                 *mangled += n;
3614               }
3615             else if (**mangled == 'X' || **mangled == 'Y')
3616               {
3617                 string temp;
3618                 do_type (work, mangled, &temp);
3619                 string_prepends (&decl, &temp);
3620               }
3621             else if (**mangled == 't')
3622               {
3623                 string temp;
3624                 string_init (&temp);
3625                 success = demangle_template (work, mangled, &temp,
3626                                              NULL, 1, 1);
3627                 if (success)
3628                   {
3629                     string_prependn (&decl, temp.b, temp.p - temp.b);
3630                     string_clear (&temp);
3631                   }
3632                 else
3633                   break;
3634               }
3635             else if (**mangled == 'Q')
3636               {
3637                 success = demangle_qualified (work, mangled, &decl,
3638                                               /*isfuncnam=*/0, 
3639                                               /*append=*/0);
3640                 if (!success)
3641                   break;
3642               }
3643             else
3644               {
3645                 success = 0;
3646                 break;
3647               }
3648
3649             string_prepend (&decl, "(");
3650             if (member)
3651               {
3652                 switch (**mangled)
3653                   {
3654                   case 'C':
3655                   case 'V':
3656                   case 'u':
3657                     type_quals |= code_for_qualifier (**mangled);
3658                     (*mangled)++;
3659                     break;
3660
3661                   default:
3662                     break;
3663                   }
3664
3665                 if (*(*mangled)++ != 'F')
3666                   {
3667                     success = 0;
3668                     break;
3669                   }
3670               }
3671             if ((member && !demangle_nested_args (work, mangled, &decl))
3672                 || **mangled != '_')
3673               {
3674                 success = 0;
3675                 break;
3676               }
3677             (*mangled)++;
3678             if (! PRINT_ANSI_QUALIFIERS)
3679               {
3680                 break;
3681               }
3682             if (type_quals != TYPE_UNQUALIFIED)
3683               {
3684                 APPEND_BLANK (&decl);
3685                 string_append (&decl, qualifier_string (type_quals));
3686               }
3687             break;
3688           }
3689         case 'G':
3690           (*mangled)++;
3691           break;
3692
3693         case 'C':
3694         case 'V':
3695         case 'u':
3696           if (PRINT_ANSI_QUALIFIERS)
3697             {
3698               if (!STRING_EMPTY (&decl))
3699                 string_prepend (&decl, " ");
3700
3701               string_prepend (&decl, demangle_qualifier (**mangled));
3702             }
3703           (*mangled)++;
3704           break;
3705           /*
3706             }
3707             */
3708
3709           /* fall through */
3710         default:
3711           done = 1;
3712           break;
3713         }
3714     }
3715
3716   if (success) switch (**mangled)
3717     {
3718       /* A qualified name, such as "Outer::Inner".  */
3719     case 'Q':
3720     case 'K':
3721       {
3722         success = demangle_qualified (work, mangled, result, 0, 1);
3723         break;
3724       }
3725
3726     /* A back reference to a previously seen squangled type */
3727     case 'B':
3728       (*mangled)++;
3729       if (!get_count (mangled, &n) || n >= work -> numb)
3730         success = 0;
3731       else
3732         string_append (result, work->btypevec[n]);
3733       break;
3734
3735     case 'X':
3736     case 'Y':
3737       /* A template parm.  We substitute the corresponding argument. */
3738       {
3739         int idx;
3740
3741         (*mangled)++;
3742         idx = consume_count_with_underscores (mangled);
3743
3744         if (idx == -1
3745             || (work->tmpl_argvec && idx >= work->ntmpl_args)
3746             || consume_count_with_underscores (mangled) == -1)
3747           {
3748             success = 0;
3749             break;
3750           }
3751
3752         if (work->tmpl_argvec)
3753           string_append (result, work->tmpl_argvec[idx]);
3754         else
3755           string_append_template_idx (result, idx);
3756
3757         success = 1;
3758       }
3759     break;
3760
3761     default:
3762       success = demangle_fund_type (work, mangled, result);
3763       if (tk == tk_none)
3764         tk = (type_kind_t) success;
3765       break;
3766     }
3767
3768   if (success)
3769     {
3770       if (!STRING_EMPTY (&decl))
3771         {
3772           string_append (result, " ");
3773           string_appends (result, &decl);
3774         }
3775     }
3776   else
3777     string_delete (result);
3778   string_delete (&decl);
3779
3780   if (success)
3781     /* Assume an integral type, if we're not sure.  */
3782     return (int) ((tk == tk_none) ? tk_integral : tk);
3783   else
3784     return 0;
3785 }
3786
3787 /* Given a pointer to a type string that represents a fundamental type
3788    argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3789    string in which the demangled output is being built in RESULT, and
3790    the WORK structure, decode the types and add them to the result.
3791
3792    For example:
3793
3794         "Ci"    =>      "const int"
3795         "Sl"    =>      "signed long"
3796         "CUs"   =>      "const unsigned short"
3797
3798    The value returned is really a type_kind_t.  */
3799
3800 static int
3801 demangle_fund_type (work, mangled, result)
3802      struct work_stuff *work;
3803      const char **mangled;
3804      string *result;
3805 {
3806   int done = 0;
3807   int success = 1;
3808   char buf[10];
3809   unsigned int dec = 0;
3810   string btype;
3811   type_kind_t tk = tk_integral;
3812
3813   string_init (&btype);
3814
3815   /* First pick off any type qualifiers.  There can be more than one.  */
3816
3817   while (!done)
3818     {
3819       switch (**mangled)
3820         {
3821         case 'C':
3822         case 'V':
3823         case 'u':
3824           if (PRINT_ANSI_QUALIFIERS)
3825             {
3826               if (!STRING_EMPTY (result))
3827                 string_prepend (result, " ");
3828               string_prepend (result, demangle_qualifier (**mangled));
3829             }
3830           (*mangled)++;
3831           break;
3832         case 'U':
3833           (*mangled)++;
3834           APPEND_BLANK (result);
3835           string_append (result, "unsigned");
3836           break;
3837         case 'S': /* signed char only */
3838           (*mangled)++;
3839           APPEND_BLANK (result);
3840           string_append (result, "signed");
3841           break;
3842         case 'J':
3843           (*mangled)++;
3844           APPEND_BLANK (result);
3845           string_append (result, "__complex");
3846           break;
3847         default:
3848           done = 1;
3849           break;
3850         }
3851     }
3852
3853   /* Now pick off the fundamental type.  There can be only one.  */
3854
3855   switch (**mangled)
3856     {
3857     case '\0':
3858     case '_':
3859       break;
3860     case 'v':
3861       (*mangled)++;
3862       APPEND_BLANK (result);
3863       string_append (result, "void");
3864       break;
3865     case 'x':
3866       (*mangled)++;
3867       APPEND_BLANK (result);
3868       string_append (result, "long long");
3869       break;
3870     case 'l':
3871       (*mangled)++;
3872       APPEND_BLANK (result);
3873       string_append (result, "long");
3874       break;
3875     case 'i':
3876       (*mangled)++;
3877       APPEND_BLANK (result);
3878       string_append (result, "int");
3879       break;
3880     case 's':
3881       (*mangled)++;
3882       APPEND_BLANK (result);
3883       string_append (result, "short");
3884       break;
3885     case 'b':
3886       (*mangled)++;
3887       APPEND_BLANK (result);
3888       string_append (result, "bool");
3889       tk = tk_bool;
3890       break;
3891     case 'c':
3892       (*mangled)++;
3893       APPEND_BLANK (result);
3894       string_append (result, "char");
3895       tk = tk_char;
3896       break;
3897     case 'w':
3898       (*mangled)++;
3899       APPEND_BLANK (result);
3900       string_append (result, "wchar_t");
3901       tk = tk_char;
3902       break;
3903     case 'r':
3904       (*mangled)++;
3905       APPEND_BLANK (result);
3906       string_append (result, "long double");
3907       tk = tk_real;
3908       break;
3909     case 'd':
3910       (*mangled)++;
3911       APPEND_BLANK (result);
3912       string_append (result, "double");
3913       tk = tk_real;
3914       break;
3915     case 'f':
3916       (*mangled)++;
3917       APPEND_BLANK (result);
3918       string_append (result, "float");
3919       tk = tk_real;
3920       break;
3921     case 'G':
3922       (*mangled)++;
3923       if (!ISDIGIT ((unsigned char)**mangled))
3924         {
3925           success = 0;
3926           break;
3927         }
3928     case 'I':
3929       (*mangled)++;
3930       if (**mangled == '_')
3931         {
3932           int i;
3933           (*mangled)++;
3934           for (i = 0;
3935                i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3936                (*mangled)++, i++)
3937             buf[i] = **mangled;
3938           if (**mangled != '_')
3939             {
3940               success = 0;
3941               break;
3942             }
3943           buf[i] = '\0';
3944           (*mangled)++;
3945         }
3946       else
3947         {
3948           strncpy (buf, *mangled, 2);
3949           buf[2] = '\0';
3950           *mangled += min (strlen (*mangled), 2);
3951         }
3952       sscanf (buf, "%x", &dec);
3953       sprintf (buf, "int%u_t", dec);
3954       APPEND_BLANK (result);
3955       string_append (result, buf);
3956       break;
3957
3958       /* fall through */
3959       /* An explicit type, such as "6mytype" or "7integer" */
3960     case '0':
3961     case '1':
3962     case '2':
3963     case '3':
3964     case '4':
3965     case '5':
3966     case '6':
3967     case '7':
3968     case '8':
3969     case '9':
3970       {
3971         int bindex = register_Btype (work);
3972         string btype;
3973         string_init (&btype);
3974         if (demangle_class_name (work, mangled, &btype)) {
3975           remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3976           APPEND_BLANK (result);
3977           string_appends (result, &btype);
3978         }
3979         else
3980           success = 0;
3981         string_delete (&btype);
3982         break;
3983       }
3984     case 't':
3985       {
3986         success = demangle_template (work, mangled, &btype, 0, 1, 1);
3987         string_appends (result, &btype);
3988         break;
3989       }
3990     default:
3991       success = 0;
3992       break;
3993     }
3994
3995   return success ? ((int) tk) : 0;
3996 }
3997
3998
3999 /* Handle a template's value parameter for HP aCC (extension from ARM)
4000    **mangled points to 'S' or 'U' */
4001
4002 static int
4003 do_hpacc_template_const_value (work, mangled, result)
4004      struct work_stuff *work ATTRIBUTE_UNUSED;
4005      const char **mangled;
4006      string *result;
4007 {
4008   int unsigned_const;
4009
4010   if (**mangled != 'U' && **mangled != 'S')
4011     return 0;
4012
4013   unsigned_const = (**mangled == 'U');
4014
4015   (*mangled)++;
4016
4017   switch (**mangled)
4018     {
4019       case 'N':
4020         string_append (result, "-");
4021         /* fall through */
4022       case 'P':
4023         (*mangled)++;
4024         break;
4025       case 'M':
4026         /* special case for -2^31 */
4027         string_append (result, "-2147483648");
4028         (*mangled)++;
4029         return 1;
4030       default:
4031         return 0;
4032     }
4033
4034   /* We have to be looking at an integer now */
4035   if (!(ISDIGIT ((unsigned char)**mangled)))
4036     return 0;
4037
4038   /* We only deal with integral values for template
4039      parameters -- so it's OK to look only for digits */
4040   while (ISDIGIT ((unsigned char)**mangled))
4041     {
4042       char_str[0] = **mangled;
4043       string_append (result, char_str);
4044       (*mangled)++;
4045     }
4046
4047   if (unsigned_const)
4048     string_append (result, "U");
4049
4050   /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4051      with L or LL suffixes. pai/1997-09-03 */
4052
4053   return 1; /* success */
4054 }
4055
4056 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4057    **mangled is pointing to the 'A' */
4058
4059 static int
4060 do_hpacc_template_literal (work, mangled, result)
4061      struct work_stuff *work;
4062      const char **mangled;
4063      string *result;
4064 {
4065   int literal_len = 0;
4066   char * recurse;
4067   char * recurse_dem;
4068
4069   if (**mangled != 'A')
4070     return 0;
4071
4072   (*mangled)++;
4073
4074   literal_len = consume_count (mangled);
4075
4076   if (literal_len <= 0)
4077     return 0;
4078
4079   /* Literal parameters are names of arrays, functions, etc.  and the
4080      canonical representation uses the address operator */
4081   string_append (result, "&");
4082
4083   /* Now recursively demangle the literal name */
4084   recurse = (char *) xmalloc (literal_len + 1);
4085   memcpy (recurse, *mangled, literal_len);
4086   recurse[literal_len] = '\000';
4087
4088   recurse_dem = cplus_demangle (recurse, work->options);
4089
4090   if (recurse_dem)
4091     {
4092       string_append (result, recurse_dem);
4093       free (recurse_dem);
4094     }
4095   else
4096     {
4097       string_appendn (result, *mangled, literal_len);
4098     }
4099   (*mangled) += literal_len;
4100   free (recurse);
4101
4102   return 1;
4103 }
4104
4105 static int
4106 snarf_numeric_literal (args, arg)
4107      const char ** args;
4108      string * arg;
4109 {
4110   if (**args == '-')
4111     {
4112       char_str[0] = '-';
4113       string_append (arg, char_str);
4114       (*args)++;
4115     }
4116   else if (**args == '+')
4117     (*args)++;
4118
4119   if (!ISDIGIT ((unsigned char)**args))
4120     return 0;
4121
4122   while (ISDIGIT ((unsigned char)**args))
4123     {
4124       char_str[0] = **args;
4125       string_append (arg, char_str);
4126       (*args)++;
4127     }
4128
4129   return 1;
4130 }
4131
4132 /* Demangle the next argument, given by MANGLED into RESULT, which
4133    *should be an uninitialized* string.  It will be initialized here,
4134    and free'd should anything go wrong.  */
4135
4136 static int
4137 do_arg (work, mangled, result)
4138      struct work_stuff *work;
4139      const char **mangled;
4140      string *result;
4141 {
4142   /* Remember where we started so that we can record the type, for
4143      non-squangling type remembering.  */
4144   const char *start = *mangled;
4145
4146   string_init (result);
4147
4148   if (work->nrepeats > 0)
4149     {
4150       --work->nrepeats;
4151
4152       if (work->previous_argument == 0)
4153         return 0;
4154
4155       /* We want to reissue the previous type in this argument list.  */
4156       string_appends (result, work->previous_argument);
4157       return 1;
4158     }
4159
4160   if (**mangled == 'n')
4161     {
4162       /* A squangling-style repeat.  */
4163       (*mangled)++;
4164       work->nrepeats = consume_count(mangled);
4165
4166       if (work->nrepeats <= 0)
4167         /* This was not a repeat count after all.  */
4168         return 0;
4169
4170       if (work->nrepeats > 9)
4171         {
4172           if (**mangled != '_')
4173             /* The repeat count should be followed by an '_' in this
4174                case.  */
4175             return 0;
4176           else
4177             (*mangled)++;
4178         }
4179
4180       /* Now, the repeat is all set up.  */
4181       return do_arg (work, mangled, result);
4182     }
4183
4184   /* Save the result in WORK->previous_argument so that we can find it
4185      if it's repeated.  Note that saving START is not good enough: we
4186      do not want to add additional types to the back-referenceable
4187      type vector when processing a repeated type.  */
4188   if (work->previous_argument)
4189     string_clear (work->previous_argument);
4190   else
4191     {
4192       work->previous_argument = (string*) xmalloc (sizeof (string));
4193       string_init (work->previous_argument);
4194     }
4195
4196   if (!do_type (work, mangled, work->previous_argument))
4197     return 0;
4198
4199   string_appends (result, work->previous_argument);
4200
4201   remember_type (work, start, *mangled - start);
4202   return 1;
4203 }
4204
4205 static void
4206 remember_type (work, start, len)
4207      struct work_stuff *work;
4208      const char *start;
4209      int len;
4210 {
4211   char *tem;
4212
4213   if (work->forgetting_types)
4214     return;
4215
4216   if (work -> ntypes >= work -> typevec_size)
4217     {
4218       if (work -> typevec_size == 0)
4219         {
4220           work -> typevec_size = 3;
4221           work -> typevec
4222             = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
4223         }
4224       else
4225         {
4226           work -> typevec_size *= 2;
4227           work -> typevec
4228             = (char **) xrealloc ((char *)work -> typevec,
4229                                   sizeof (char *) * work -> typevec_size);
4230         }
4231     }
4232   tem = xmalloc (len + 1);
4233   memcpy (tem, start, len);
4234   tem[len] = '\0';
4235   work -> typevec[work -> ntypes++] = tem;
4236 }
4237
4238
4239 /* Remember a K type class qualifier. */
4240 static void
4241 remember_Ktype (work, start, len)
4242      struct work_stuff *work;
4243      const char *start;
4244      int len;
4245 {
4246   char *tem;
4247
4248   if (work -> numk >= work -> ksize)
4249     {
4250       if (work -> ksize == 0)
4251         {
4252           work -> ksize = 5;
4253           work -> ktypevec
4254             = (char **) xmalloc (sizeof (char *) * work -> ksize);
4255         }
4256       else
4257         {
4258           work -> ksize *= 2;
4259           work -> ktypevec
4260             = (char **) xrealloc ((char *)work -> ktypevec,
4261                                   sizeof (char *) * work -> ksize);
4262         }
4263     }
4264   tem = xmalloc (len + 1);
4265   memcpy (tem, start, len);
4266   tem[len] = '\0';
4267   work -> ktypevec[work -> numk++] = tem;
4268 }
4269
4270 /* Register a B code, and get an index for it. B codes are registered
4271    as they are seen, rather than as they are completed, so map<temp<char> >
4272    registers map<temp<char> > as B0, and temp<char> as B1 */
4273
4274 static int
4275 register_Btype (work)
4276      struct work_stuff *work;
4277 {
4278   int ret;
4279
4280   if (work -> numb >= work -> bsize)
4281     {
4282       if (work -> bsize == 0)
4283         {
4284           work -> bsize = 5;
4285           work -> btypevec
4286             = (char **) xmalloc (sizeof (char *) * work -> bsize);
4287         }
4288       else
4289         {
4290           work -> bsize *= 2;
4291           work -> btypevec
4292             = (char **) xrealloc ((char *)work -> btypevec,
4293                                   sizeof (char *) * work -> bsize);
4294         }
4295     }
4296   ret = work -> numb++;
4297   work -> btypevec[ret] = NULL;
4298   return(ret);
4299 }
4300
4301 /* Store a value into a previously registered B code type. */
4302
4303 static void
4304 remember_Btype (work, start, len, index)
4305      struct work_stuff *work;
4306      const char *start;
4307      int len, index;
4308 {
4309   char *tem;
4310
4311   tem = xmalloc (len + 1);
4312   memcpy (tem, start, len);
4313   tem[len] = '\0';
4314   work -> btypevec[index] = tem;
4315 }
4316
4317 /* Lose all the info related to B and K type codes. */
4318 static void
4319 forget_B_and_K_types (work)
4320      struct work_stuff *work;
4321 {
4322   int i;
4323
4324   while (work -> numk > 0)
4325     {
4326       i = --(work -> numk);
4327       if (work -> ktypevec[i] != NULL)
4328         {
4329           free (work -> ktypevec[i]);
4330           work -> ktypevec[i] = NULL;
4331         }
4332     }
4333
4334   while (work -> numb > 0)
4335     {
4336       i = --(work -> numb);
4337       if (work -> btypevec[i] != NULL)
4338         {
4339           free (work -> btypevec[i]);
4340           work -> btypevec[i] = NULL;
4341         }
4342     }
4343 }
4344 /* Forget the remembered types, but not the type vector itself.  */
4345
4346 static void
4347 forget_types (work)
4348      struct work_stuff *work;
4349 {
4350   int i;
4351
4352   while (work -> ntypes > 0)
4353     {
4354       i = --(work -> ntypes);
4355       if (work -> typevec[i] != NULL)
4356         {
4357           free (work -> typevec[i]);
4358           work -> typevec[i] = NULL;
4359         }
4360     }
4361 }
4362
4363 /* Process the argument list part of the signature, after any class spec
4364    has been consumed, as well as the first 'F' character (if any).  For
4365    example:
4366
4367    "__als__3fooRT0"             =>      process "RT0"
4368    "complexfunc5__FPFPc_PFl_i"  =>      process "PFPc_PFl_i"
4369
4370    DECLP must be already initialised, usually non-empty.  It won't be freed
4371    on failure.
4372
4373    Note that g++ differs significantly from ARM and lucid style mangling
4374    with regards to references to previously seen types.  For example, given
4375    the source fragment:
4376
4377      class foo {
4378        public:
4379        foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4380      };
4381
4382      foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4383      void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4384
4385    g++ produces the names:
4386
4387      __3fooiRT0iT2iT2
4388      foo__FiR3fooiT1iT1
4389
4390    while lcc (and presumably other ARM style compilers as well) produces:
4391
4392      foo__FiR3fooT1T2T1T2
4393      __ct__3fooFiR3fooT1T2T1T2
4394
4395    Note that g++ bases its type numbers starting at zero and counts all
4396    previously seen types, while lucid/ARM bases its type numbers starting
4397    at one and only considers types after it has seen the 'F' character
4398    indicating the start of the function args.  For lucid/ARM style, we
4399    account for this difference by discarding any previously seen types when
4400    we see the 'F' character, and subtracting one from the type number
4401    reference.
4402
4403  */
4404
4405 static int
4406 demangle_args (work, mangled, declp)
4407      struct work_stuff *work;
4408      const char **mangled;
4409      string *declp;
4410 {
4411   string arg;
4412   int need_comma = 0;
4413   int r;
4414   int t;
4415   const char *tem;
4416   char temptype;
4417
4418   if (PRINT_ARG_TYPES)
4419     {
4420       string_append (declp, "(");
4421       if (**mangled == '\0')
4422         {
4423           string_append (declp, "void");
4424         }
4425     }
4426
4427   while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4428          || work->nrepeats > 0)
4429     {
4430       if ((**mangled == 'N') || (**mangled == 'T'))
4431         {
4432           temptype = *(*mangled)++;
4433
4434           if (temptype == 'N')
4435             {
4436               if (!get_count (mangled, &r))
4437                 {
4438                   return (0);
4439                 }
4440             }
4441           else
4442             {
4443               r = 1;
4444             }
4445           if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4446             {
4447               /* If we have 10 or more types we might have more than a 1 digit
4448                  index so we'll have to consume the whole count here. This
4449                  will lose if the next thing is a type name preceded by a
4450                  count but it's impossible to demangle that case properly
4451                  anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4452                  Pc, ...)"  or "(..., type12, char *, ...)" */
4453               if ((t = consume_count(mangled)) <= 0)
4454                 {
4455                   return (0);
4456                 }
4457             }
4458           else
4459             {
4460               if (!get_count (mangled, &t))
4461                 {
4462                   return (0);
4463                 }
4464             }
4465           if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4466             {
4467               t--;
4468             }
4469           /* Validate the type index.  Protect against illegal indices from
4470              malformed type strings.  */
4471           if ((t < 0) || (t >= work -> ntypes))
4472             {
4473               return (0);
4474             }
4475           while (work->nrepeats > 0 || --r >= 0)
4476             {
4477               tem = work -> typevec[t];
4478               if (need_comma && PRINT_ARG_TYPES)
4479                 {
4480                   string_append (declp, ", ");
4481                 }
4482               if (!do_arg (work, &tem, &arg))
4483                 {
4484                   return (0);
4485                 }
4486               if (PRINT_ARG_TYPES)
4487                 {
4488                   string_appends (declp, &arg);
4489                 }
4490               string_delete (&arg);
4491               need_comma = 1;
4492             }
4493         }
4494       else
4495         {
4496           if (need_comma && PRINT_ARG_TYPES)
4497             string_append (declp, ", ");
4498           if (!do_arg (work, mangled, &arg))
4499             return (0);
4500           if (PRINT_ARG_TYPES)
4501             string_appends (declp, &arg);
4502           string_delete (&arg);
4503           need_comma = 1;
4504         }
4505     }
4506
4507   if (**mangled == 'e')
4508     {
4509       (*mangled)++;
4510       if (PRINT_ARG_TYPES)
4511         {
4512           if (need_comma)
4513             {
4514               string_append (declp, ",");
4515             }
4516           string_append (declp, "...");
4517         }
4518     }
4519
4520   if (PRINT_ARG_TYPES)
4521     {
4522       string_append (declp, ")");
4523     }
4524   return (1);
4525 }
4526
4527 /* Like demangle_args, but for demangling the argument lists of function
4528    and method pointers or references, not top-level declarations.  */
4529
4530 static int
4531 demangle_nested_args (work, mangled, declp)
4532      struct work_stuff *work;
4533      const char **mangled;
4534      string *declp;
4535 {
4536   string* saved_previous_argument;
4537   int result;
4538   int saved_nrepeats;
4539
4540   /* The G++ name-mangling algorithm does not remember types on nested
4541      argument lists, unless -fsquangling is used, and in that case the
4542      type vector updated by remember_type is not used.  So, we turn
4543      off remembering of types here.  */
4544   ++work->forgetting_types;
4545
4546   /* For the repeat codes used with -fsquangling, we must keep track of
4547      the last argument.  */
4548   saved_previous_argument = work->previous_argument;
4549   saved_nrepeats = work->nrepeats;
4550   work->previous_argument = 0;
4551   work->nrepeats = 0;
4552
4553   /* Actually demangle the arguments.  */
4554   result = demangle_args (work, mangled, declp);
4555
4556   /* Restore the previous_argument field.  */
4557   if (work->previous_argument)
4558     string_delete (work->previous_argument);
4559   work->previous_argument = saved_previous_argument;
4560   --work->forgetting_types;
4561   work->nrepeats = saved_nrepeats;
4562
4563   return result;
4564 }
4565
4566 static void
4567 demangle_function_name (work, mangled, declp, scan)
4568      struct work_stuff *work;
4569      const char **mangled;
4570      string *declp;
4571      const char *scan;
4572 {
4573   size_t i;
4574   string type;
4575   const char *tem;
4576
4577   string_appendn (declp, (*mangled), scan - (*mangled));
4578   string_need (declp, 1);
4579   *(declp -> p) = '\0';
4580
4581   /* Consume the function name, including the "__" separating the name
4582      from the signature.  We are guaranteed that SCAN points to the
4583      separator.  */
4584
4585   (*mangled) = scan + 2;
4586   /* We may be looking at an instantiation of a template function:
4587      foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4588      following _F marks the start of the function arguments.  Handle
4589      the template arguments first. */
4590
4591   if (HP_DEMANGLING && (**mangled == 'X'))
4592     {
4593       demangle_arm_hp_template (work, mangled, 0, declp);
4594       /* This leaves MANGLED pointing to the 'F' marking func args */
4595     }
4596
4597   if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4598     {
4599
4600       /* See if we have an ARM style constructor or destructor operator.
4601          If so, then just record it, clear the decl, and return.
4602          We can't build the actual constructor/destructor decl until later,
4603          when we recover the class name from the signature.  */
4604
4605       if (strcmp (declp -> b, "__ct") == 0)
4606         {
4607           work -> constructor += 1;
4608           string_clear (declp);
4609           return;
4610         }
4611       else if (strcmp (declp -> b, "__dt") == 0)
4612         {
4613           work -> destructor += 1;
4614           string_clear (declp);
4615           return;
4616         }
4617     }
4618
4619   if (declp->p - declp->b >= 3
4620       && declp->b[0] == 'o'
4621       && declp->b[1] == 'p'
4622       && strchr (cplus_markers, declp->b[2]) != NULL)
4623     {
4624       /* see if it's an assignment expression */
4625       if (declp->p - declp->b >= 10 /* op$assign_ */
4626           && memcmp (declp->b + 3, "assign_", 7) == 0)
4627         {
4628           for (i = 0; i < ARRAY_SIZE (optable); i++)
4629             {
4630               int len = declp->p - declp->b - 10;
4631               if ((int) strlen (optable[i].in) == len
4632                   && memcmp (optable[i].in, declp->b + 10, len) == 0)
4633                 {
4634                   string_clear (declp);
4635                   string_append (declp, "operator");
4636                   string_append (declp, optable[i].out);
4637                   string_append (declp, "=");
4638                   break;
4639                 }
4640             }
4641         }
4642       else
4643         {
4644           for (i = 0; i < ARRAY_SIZE (optable); i++)
4645             {
4646               int len = declp->p - declp->b - 3;
4647               if ((int) strlen (optable[i].in) == len
4648                   && memcmp (optable[i].in, declp->b + 3, len) == 0)
4649                 {
4650                   string_clear (declp);
4651                   string_append (declp, "operator");
4652                   string_append (declp, optable[i].out);
4653                   break;
4654                 }
4655             }
4656         }
4657     }
4658   else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4659            && strchr (cplus_markers, declp->b[4]) != NULL)
4660     {
4661       /* type conversion operator */
4662       tem = declp->b + 5;
4663       if (do_type (work, &tem, &type))
4664         {
4665           string_clear (declp);
4666           string_append (declp, "operator ");
4667           string_appends (declp, &type);
4668           string_delete (&type);
4669         }
4670     }
4671   else if (declp->b[0] == '_' && declp->b[1] == '_'
4672            && declp->b[2] == 'o' && declp->b[3] == 'p')
4673     {
4674       /* ANSI.  */
4675       /* type conversion operator.  */
4676       tem = declp->b + 4;
4677       if (do_type (work, &tem, &type))
4678         {
4679           string_clear (declp);
4680           string_append (declp, "operator ");
4681           string_appends (declp, &type);
4682           string_delete (&type);
4683         }
4684     }
4685   else if (declp->b[0] == '_' && declp->b[1] == '_'
4686            && ISLOWER((unsigned char)declp->b[2])
4687            && ISLOWER((unsigned char)declp->b[3]))
4688     {
4689       if (declp->b[4] == '\0')
4690         {
4691           /* Operator.  */
4692           for (i = 0; i < ARRAY_SIZE (optable); i++)
4693             {
4694               if (strlen (optable[i].in) == 2
4695                   && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4696                 {
4697                   string_clear (declp);
4698                   string_append (declp, "operator");
4699                   string_append (declp, optable[i].out);
4700                   break;
4701                 }
4702             }
4703         }
4704       else
4705         {
4706           if (declp->b[2] == 'a' && declp->b[5] == '\0')
4707             {
4708               /* Assignment.  */
4709               for (i = 0; i < ARRAY_SIZE (optable); i++)
4710                 {
4711                   if (strlen (optable[i].in) == 3
4712                       && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4713                     {
4714                       string_clear (declp);
4715                       string_append (declp, "operator");
4716                       string_append (declp, optable[i].out);
4717                       break;
4718                     }
4719                 }
4720             }
4721         }
4722     }
4723 }
4724
4725 /* a mini string-handling package */
4726
4727 static void
4728 string_need (s, n)
4729      string *s;
4730      int n;
4731 {
4732   int tem;
4733
4734   if (s->b == NULL)
4735     {
4736       if (n < 32)
4737         {
4738           n = 32;
4739         }
4740       s->p = s->b = xmalloc (n);
4741       s->e = s->b + n;
4742     }
4743   else if (s->e - s->p < n)
4744     {
4745       tem = s->p - s->b;
4746       n += tem;
4747       n *= 2;
4748       s->b = xrealloc (s->b, n);
4749       s->p = s->b + tem;
4750       s->e = s->b + n;
4751     }
4752 }
4753
4754 static void
4755 string_delete (s)
4756      string *s;
4757 {
4758   if (s->b != NULL)
4759     {
4760       free (s->b);
4761       s->b = s->e = s->p = NULL;
4762     }
4763 }
4764
4765 static void
4766 string_init (s)
4767      string *s;
4768 {
4769   s->b = s->p = s->e = NULL;
4770 }
4771
4772 static void
4773 string_clear (s)
4774      string *s;
4775 {
4776   s->p = s->b;
4777 }
4778
4779 #if 0
4780
4781 static int
4782 string_empty (s)
4783      string *s;
4784 {
4785   return (s->b == s->p);
4786 }
4787
4788 #endif
4789
4790 static void
4791 string_append (p, s)
4792      string *p;
4793      const char *s;
4794 {
4795   int n;
4796   if (s == NULL || *s == '\0')
4797     return;
4798   n = strlen (s);
4799   string_need (p, n);
4800   memcpy (p->p, s, n);
4801   p->p += n;
4802 }
4803
4804 static void
4805 string_appends (p, s)
4806      string *p, *s;
4807 {
4808   int n;
4809
4810   if (s->b != s->p)
4811     {
4812       n = s->p - s->b;
4813       string_need (p, n);
4814       memcpy (p->p, s->b, n);
4815       p->p += n;
4816     }
4817 }
4818
4819 static void
4820 string_appendn (p, s, n)
4821      string *p;
4822      const char *s;
4823      int n;
4824 {
4825   if (n != 0)
4826     {
4827       string_need (p, n);
4828       memcpy (p->p, s, n);
4829       p->p += n;
4830     }
4831 }
4832
4833 static void
4834 string_prepend (p, s)
4835      string *p;
4836      const char *s;
4837 {
4838   if (s != NULL && *s != '\0')
4839     {
4840       string_prependn (p, s, strlen (s));
4841     }
4842 }
4843
4844 static void
4845 string_prepends (p, s)
4846      string *p, *s;
4847 {
4848   if (s->b != s->p)
4849     {
4850       string_prependn (p, s->b, s->p - s->b);
4851     }
4852 }
4853
4854 static void
4855 string_prependn (p, s, n)
4856      string *p;
4857      const char *s;
4858      int n;
4859 {
4860   char *q;
4861
4862   if (n != 0)
4863     {
4864       string_need (p, n);
4865       for (q = p->p - 1; q >= p->b; q--)
4866         {
4867           q[n] = q[0];
4868         }
4869       memcpy (p->b, s, n);
4870       p->p += n;
4871     }
4872 }
4873
4874 static void
4875 string_append_template_idx (s, idx)
4876      string *s;
4877      int idx;
4878 {
4879   char buf[INTBUF_SIZE + 1 /* 'T' */];
4880   sprintf(buf, "T%d", idx);
4881   string_append (s, buf);
4882 }
4883
4884 /* To generate a standalone demangler program for testing purposes,
4885    just compile and link this file with -DMAIN and libiberty.a.  When
4886    run, it demangles each command line arg, or each stdin string, and
4887    prints the result on stdout.  */
4888
4889 #ifdef MAIN
4890
4891 #include "getopt.h"
4892
4893 static const char *program_name;
4894 static const char *program_version = VERSION;
4895 static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE;
4896
4897 static void demangle_it PARAMS ((char *));
4898 static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
4899 static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
4900 static void print_demangler_list PARAMS ((FILE *));
4901
4902 static void
4903 demangle_it (mangled_name)
4904      char *mangled_name;
4905 {
4906   char *result;
4907
4908   /* For command line args, also try to demangle type encodings.  */
4909   result = cplus_demangle (mangled_name, flags | DMGL_TYPES);
4910   if (result == NULL)
4911     {
4912       printf ("%s\n", mangled_name);
4913     }
4914   else
4915     {
4916       printf ("%s\n", result);
4917       free (result);
4918     }
4919 }
4920
4921 static void 
4922 print_demangler_list (stream)
4923      FILE *stream;
4924 {
4925   const struct demangler_engine *demangler; 
4926
4927   fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
4928   
4929   for (demangler = libiberty_demanglers + 1;
4930        demangler->demangling_style != unknown_demangling;
4931        ++demangler)
4932     fprintf (stream, ",%s", demangler->demangling_style_name);
4933
4934   fprintf (stream, "}");
4935 }
4936
4937 static void
4938 usage (stream, status)
4939      FILE *stream;
4940      int status;
4941 {
4942   fprintf (stream, "\
4943 Usage: %s [-_] [-n] [--strip-underscores] [--no-strip-underscores] \n",
4944            program_name);
4945
4946   fprintf (stream, "\
4947        [-s ");
4948   print_demangler_list (stream);
4949   fprintf (stream, "]\n");
4950
4951   fprintf (stream, "\
4952        [--format ");
4953   print_demangler_list (stream);
4954   fprintf (stream, "]\n");
4955
4956   fprintf (stream, "\
4957        [--help] [--version] [arg...]\n");
4958   exit (status);
4959 }
4960
4961 #define MBUF_SIZE 32767
4962 char mbuffer[MBUF_SIZE];
4963
4964 /* Defined in the automatically-generated underscore.c.  */
4965 extern int prepends_underscore;
4966
4967 int strip_underscore = 0;
4968
4969 static const struct option long_options[] = {
4970   {"strip-underscores", no_argument, 0, '_'},
4971   {"format", required_argument, 0, 's'},
4972   {"help", no_argument, 0, 'h'},
4973   {"no-strip-underscores", no_argument, 0, 'n'},
4974   {"version", no_argument, 0, 'v'},
4975   {0, no_argument, 0, 0}
4976 };
4977
4978 /* More 'friendly' abort that prints the line and file.
4979    config.h can #define abort fancy_abort if you like that sort of thing.  */
4980
4981 void
4982 fancy_abort ()
4983 {
4984   fatal ("Internal gcc abort.");
4985 }
4986
4987
4988 static const char *
4989 standard_symbol_characters PARAMS ((void));
4990
4991 static const char *
4992 hp_symbol_characters PARAMS ((void));
4993
4994 static const char *
4995 gnu_v3_symbol_characters PARAMS ((void));
4996
4997 /* Return the string of non-alnum characters that may occur 
4998    as a valid symbol component, in the standard assembler symbol
4999    syntax.  */
5000
5001 static const char *
5002 standard_symbol_characters ()
5003 {
5004   return "_$.";
5005 }
5006
5007
5008 /* Return the string of non-alnum characters that may occur
5009    as a valid symbol name component in an HP object file.
5010
5011    Note that, since HP's compiler generates object code straight from
5012    C++ source, without going through an assembler, its mangled
5013    identifiers can use all sorts of characters that no assembler would
5014    tolerate, so the alphabet this function creates is a little odd.
5015    Here are some sample mangled identifiers offered by HP:
5016
5017         typeid*__XT24AddressIndExpClassMember_
5018         [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
5019         __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
5020
5021    This still seems really weird to me, since nowhere else in this
5022    file is there anything to recognize curly brackets, parens, etc.
5023    I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
5024    this is right, but I still strongly suspect that there's a
5025    misunderstanding here.
5026
5027    If we decide it's better for c++filt to use HP's assembler syntax
5028    to scrape identifiers out of its input, here's the definition of
5029    the symbol name syntax from the HP assembler manual:
5030
5031        Symbols are composed of uppercase and lowercase letters, decimal
5032        digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
5033        underscore (_). A symbol can begin with a letter, digit underscore or
5034        dollar sign. If a symbol begins with a digit, it must contain a
5035        non-digit character.
5036
5037    So have fun.  */
5038 static const char *
5039 hp_symbol_characters ()
5040 {
5041   return "_$.<>#,*&[]:(){}";
5042 }
5043
5044
5045 /* Return the string of non-alnum characters that may occur 
5046    as a valid symbol component in the GNU C++ V3 ABI mangling
5047    scheme.  */
5048
5049 static const char *
5050 gnu_v3_symbol_characters ()
5051 {
5052   return "_$.";
5053 }
5054
5055
5056 extern int main PARAMS ((int, char **));
5057
5058 int
5059 main (argc, argv)
5060      int argc;
5061      char **argv;
5062 {
5063   char *result;
5064   int c;
5065   const char *valid_symbols;
5066   enum demangling_styles style = auto_demangling;
5067
5068   program_name = argv[0];
5069
5070   strip_underscore = prepends_underscore;
5071
5072   while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
5073     {
5074       switch (c)
5075         {
5076         case '?':
5077           usage (stderr, 1);
5078           break;
5079         case 'h':
5080           usage (stdout, 0);
5081         case 'n':
5082           strip_underscore = 0;
5083           break;
5084         case 'v':
5085           printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
5086           return (0);
5087         case '_':
5088           strip_underscore = 1;
5089           break;
5090         case 's':
5091           {
5092             style = cplus_demangle_name_to_style (optarg);
5093             if (style == unknown_demangling)
5094               {
5095                 fprintf (stderr, "%s: unknown demangling style `%s'\n",
5096                          program_name, optarg);
5097                 return (1);
5098               }
5099             else
5100               cplus_demangle_set_style (style);
5101           }
5102           break;
5103         }
5104     }
5105
5106   if (optind < argc)
5107     {
5108       for ( ; optind < argc; optind++)
5109         {
5110           demangle_it (argv[optind]);
5111         }
5112     }
5113   else
5114     {
5115       switch (current_demangling_style)
5116         {
5117         case gnu_demangling:
5118         case lucid_demangling:
5119         case arm_demangling:
5120         case java_demangling:
5121         case edg_demangling:
5122         case gnat_demangling:
5123         case auto_demangling:
5124           valid_symbols = standard_symbol_characters ();
5125           break;
5126         case hp_demangling:
5127           valid_symbols = hp_symbol_characters ();
5128           break;
5129         case gnu_v3_demangling:
5130           valid_symbols = gnu_v3_symbol_characters ();
5131           break;
5132         default:
5133           /* Folks should explicitly indicate the appropriate alphabet for
5134              each demangling.  Providing a default would allow the
5135              question to go unconsidered.  */
5136           abort ();
5137         }
5138
5139       for (;;)
5140         {
5141           int i = 0;
5142           c = getchar ();
5143           /* Try to read a label.  */
5144           while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c)))
5145             {
5146               if (i >= MBUF_SIZE-1)
5147                 break;
5148               mbuffer[i++] = c;
5149               c = getchar ();
5150             }
5151           if (i > 0)
5152             {
5153               int skip_first = 0;
5154
5155               if (mbuffer[0] == '.' || mbuffer[0] == '$')
5156                 ++skip_first;
5157               if (strip_underscore && mbuffer[skip_first] == '_')
5158                 ++skip_first;
5159
5160               if (skip_first > i)
5161                 skip_first = i;
5162
5163               mbuffer[i] = 0;
5164               flags |= (int) style;
5165               result = cplus_demangle (mbuffer + skip_first, flags);
5166               if (result)
5167                 {
5168                   if (mbuffer[0] == '.')
5169                     putc ('.', stdout);
5170                   fputs (result, stdout);
5171                   free (result);
5172                 }
5173               else
5174                 fputs (mbuffer, stdout);
5175
5176               fflush (stdout);
5177             }
5178           if (c == EOF)
5179             break;
5180           putchar (c);
5181           fflush (stdout);
5182         }
5183     }
5184
5185   return (0);
5186 }
5187
5188 static void
5189 fatal (str)
5190      const char *str;
5191 {
5192   fprintf (stderr, "%s: %s\n", program_name, str);
5193   exit (1);
5194 }
5195
5196 PTR
5197 xmalloc (size)
5198   size_t size;
5199 {
5200   register PTR value = (PTR) malloc (size);
5201   if (value == 0)
5202     fatal ("virtual memory exhausted");
5203   return value;
5204 }
5205
5206 PTR
5207 xrealloc (ptr, size)
5208   PTR ptr;
5209   size_t size;
5210 {
5211   register PTR value = (PTR) realloc (ptr, size);
5212   if (value == 0)
5213     fatal ("virtual memory exhausted");
5214   return value;
5215 }
5216 #endif  /* main */