OSDN Git Service

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