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