source: rtems-tools/rtemstoolkit/libiberty/cplus-dem.c @ 3618a62

5
Last change on this file since 3618a62 was 78bbe4c, checked in by Chris Johns <chrisj@…>, on 08/16/17 at 08:09:59

linkers/exe-info Support ARM static constructors.

Note, ARM destructors are registered at runtime and currently not
easly found.

Update libiberty to get a newer demangler.

Closes #3102.

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