OSDN Git Service

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