OSDN Git Service

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