source: rtems-tools/rtemstoolkit/libiberty/cplus-dem.c @ 87e0e76

4.104.115
Last change on this file since 87e0e76 was 87e0e76, checked in by Chris Johns <chrisj@…>, on 09/13/14 at 02:09:16

Refactor code into the RTEMS Toolkit.

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