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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [libiberty/] [cplus-dem.c] - Blame information for rev 822

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

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

powered by: WebSVN 2.1.0

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