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