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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libiberty/] [cplus-dem.c] - Blame information for rev 866

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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