OSDN Git Service

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