OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libiberty/] [cplus-dem.c] - Blame information for rev 736

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.