OSDN Git Service

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