OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [libiberty/] [cplus-dem.c] - Blame information for rev 550

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
char * malloc ();
56
char * 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 void
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
    {
2497
      demangle_function_name (work, mangled, declp, scan);
2498
      return 1;
2499
    }
2500
 
2501
  /* Save state so we can restart if the guess at the correct "__" was
2502
     wrong.  */
2503
  string_init (&decl_init);
2504
  string_appends (&decl_init, declp);
2505
  memset (&work_init, 0, sizeof work_init);
2506
  work_stuff_copy_to_from (&work_init, work);
2507
 
2508
  /* Iterate over occurrences of __, allowing names and types to have a
2509
     "__" sequence in them.  We must start with the first (not the last)
2510
     occurrence, since "__" most often occur between independent mangled
2511
     parts, hence starting at the last occurence inside a signature
2512
     might get us a "successful" demangling of the signature.  */
2513
 
2514
  while (scan[2])
2515
    {
2516
      demangle_function_name (work, mangled, declp, scan);
2517
      success = demangle_signature (work, mangled, declp);
2518
      if (success)
2519
        break;
2520
 
2521
      /* Reset demangle state for the next round.  */
2522
      *mangled = mangle_init;
2523
      string_clear (declp);
2524
      string_appends (declp, &decl_init);
2525
      work_stuff_copy_to_from (work, &work_init);
2526
 
2527
      /* Leave this underscore-sequence.  */
2528
      scan += 2;
2529
 
2530
      /* Scan for the next "__" sequence.  */
2531
      while (*scan && (scan[0] != '_' || scan[1] != '_'))
2532
        scan++;
2533
 
2534
      /* Move to last "__" in this sequence.  */
2535
      while (*scan && *scan == '_')
2536
        scan++;
2537
      scan -= 2;
2538
    }
2539
 
2540
  /* Delete saved state.  */
2541
  delete_work_stuff (&work_init);
2542
  string_delete (&decl_init);
2543
 
2544
  return success;
2545
}
2546
 
2547
/*
2548
 
2549
LOCAL FUNCTION
2550
 
2551
        demangle_prefix -- consume the mangled name prefix and find signature
2552
 
2553
SYNOPSIS
2554
 
2555
        static int
2556
        demangle_prefix (struct work_stuff *work, const char **mangled,
2557
                         string *declp);
2558
 
2559
DESCRIPTION
2560
 
2561
        Consume and demangle the prefix of the mangled name.
2562
        While processing the function name root, arrange to call
2563
        demangle_signature if the root is ambiguous.
2564
 
2565
        DECLP points to the string buffer into which demangled output is
2566
        placed.  On entry, the buffer is empty.  On exit it contains
2567
        the root function name, the demangled operator name, or in some
2568
        special cases either nothing or the completely demangled result.
2569
 
2570
        MANGLED points to the current pointer into the mangled name.  As each
2571
        token of the mangled name is consumed, it is updated.  Upon entry
2572
        the current mangled name pointer points to the first character of
2573
        the mangled name.  Upon exit, it should point to the first character
2574
        of the signature if demangling was successful, or to the first
2575
        unconsumed character if demangling of the prefix was unsuccessful.
2576
 
2577
        Returns 1 on success, 0 otherwise.
2578
 */
2579
 
2580
static int
2581
demangle_prefix (struct work_stuff *work, const char **mangled,
2582
                 string *declp)
2583
{
2584
  int success = 1;
2585
  const char *scan;
2586
  int i;
2587
 
2588
  if (strlen(*mangled) > 6
2589
      && (strncmp(*mangled, "_imp__", 6) == 0
2590
          || strncmp(*mangled, "__imp_", 6) == 0))
2591
    {
2592
      /* it's a symbol imported from a PE dynamic library. Check for both
2593
         new style prefix _imp__ and legacy __imp_ used by older versions
2594
         of dlltool. */
2595
      (*mangled) += 6;
2596
      work->dllimported = 1;
2597
    }
2598
  else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2599
    {
2600
      char *marker = strchr (cplus_markers, (*mangled)[8]);
2601
      if (marker != NULL && *marker == (*mangled)[10])
2602
        {
2603
          if ((*mangled)[9] == 'D')
2604
            {
2605
              /* it's a GNU global destructor to be executed at program exit */
2606
              (*mangled) += 11;
2607
              work->destructor = 2;
2608
              if (gnu_special (work, mangled, declp))
2609
                return success;
2610
            }
2611
          else if ((*mangled)[9] == 'I')
2612
            {
2613
              /* it's a GNU global constructor to be executed at program init */
2614
              (*mangled) += 11;
2615
              work->constructor = 2;
2616
              if (gnu_special (work, mangled, declp))
2617
                return success;
2618
            }
2619
        }
2620
    }
2621
  else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2622
    {
2623
      /* it's a ARM global destructor to be executed at program exit */
2624
      (*mangled) += 7;
2625
      work->destructor = 2;
2626
    }
2627
  else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2628
    {
2629
      /* it's a ARM global constructor to be executed at program initial */
2630
      (*mangled) += 7;
2631
      work->constructor = 2;
2632
    }
2633
 
2634
  /*  This block of code is a reduction in strength time optimization
2635
      of:
2636
      scan = strstr (*mangled, "__"); */
2637
 
2638
  {
2639
    scan = *mangled;
2640
 
2641
    do {
2642
      scan = strchr (scan, '_');
2643
    } while (scan != NULL && *++scan != '_');
2644
 
2645
    if (scan != NULL) --scan;
2646
  }
2647
 
2648
  if (scan != NULL)
2649
    {
2650
      /* We found a sequence of two or more '_', ensure that we start at
2651
         the last pair in the sequence.  */
2652
      i = strspn (scan, "_");
2653
      if (i > 2)
2654
        {
2655
          scan += (i - 2);
2656
        }
2657
    }
2658
 
2659
  if (scan == NULL)
2660
    {
2661
      success = 0;
2662
    }
2663
  else if (work -> static_type)
2664
    {
2665
      if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2666
        {
2667
          success = 0;
2668
        }
2669
    }
2670
  else if ((scan == *mangled)
2671
           && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2672
               || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2673
    {
2674
      /* The ARM says nothing about the mangling of local variables.
2675
         But cfront mangles local variables by prepending __<nesting_level>
2676
         to them. As an extension to ARM demangling we handle this case.  */
2677
      if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2678
          && ISDIGIT ((unsigned char)scan[2]))
2679
        {
2680
          *mangled = scan + 2;
2681
          consume_count (mangled);
2682
          string_append (declp, *mangled);
2683
          *mangled += strlen (*mangled);
2684
          success = 1;
2685
        }
2686
      else
2687
        {
2688
          /* A GNU style constructor starts with __[0-9Qt].  But cfront uses
2689
             names like __Q2_3foo3bar for nested type names.  So don't accept
2690
             this style of constructor for cfront demangling.  A GNU
2691
             style member-template constructor starts with 'H'. */
2692
          if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2693
            work -> constructor += 1;
2694
          *mangled = scan + 2;
2695
        }
2696
    }
2697
  else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2698
    {
2699
      /* Cfront-style parameterized type.  Handled later as a signature. */
2700
      success = 1;
2701
 
2702
      /* ARM template? */
2703
      demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2704
    }
2705
  else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2706
                              || (scan[2] == 'p' && scan[3] == 's')
2707
                              || (scan[2] == 'p' && scan[3] == 't')))
2708
    {
2709
      /* EDG-style parameterized type.  Handled later as a signature. */
2710
      success = 1;
2711
 
2712
      /* EDG template? */
2713
      demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2714
    }
2715
  else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2716
           && (scan[2] != 't'))
2717
    {
2718
      /* Mangled name starts with "__".  Skip over any leading '_' characters,
2719
         then find the next "__" that separates the prefix from the signature.
2720
         */
2721
      if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2722
          || (arm_special (mangled, declp) == 0))
2723
        {
2724
          while (*scan == '_')
2725
            {
2726
              scan++;
2727
            }
2728
          if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2729
            {
2730
              /* No separator (I.E. "__not_mangled"), or empty signature
2731
                 (I.E. "__not_mangled_either__") */
2732
              success = 0;
2733
            }
2734
          else
2735
            return iterate_demangle_function (work, mangled, declp, scan);
2736
        }
2737
    }
2738
  else if (*(scan + 2) != '\0')
2739
    {
2740
      /* Mangled name does not start with "__" but does have one somewhere
2741
         in there with non empty stuff after it.  Looks like a global
2742
         function name.  Iterate over all "__":s until the right
2743
         one is found.  */
2744
      return iterate_demangle_function (work, mangled, declp, scan);
2745
    }
2746
  else
2747
    {
2748
      /* Doesn't look like a mangled name */
2749
      success = 0;
2750
    }
2751
 
2752
  if (!success && (work->constructor == 2 || work->destructor == 2))
2753
    {
2754
      string_append (declp, *mangled);
2755
      *mangled += strlen (*mangled);
2756
      success = 1;
2757
    }
2758
  return (success);
2759
}
2760
 
2761
/*
2762
 
2763
LOCAL FUNCTION
2764
 
2765
        gnu_special -- special handling of gnu mangled strings
2766
 
2767
SYNOPSIS
2768
 
2769
        static int
2770
        gnu_special (struct work_stuff *work, const char **mangled,
2771
                     string *declp);
2772
 
2773
 
2774
DESCRIPTION
2775
 
2776
        Process some special GNU style mangling forms that don't fit
2777
        the normal pattern.  For example:
2778
 
2779
                _$_3foo         (destructor for class foo)
2780
                _vt$foo         (foo virtual table)
2781
                _vt$foo$bar     (foo::bar virtual table)
2782
                __vt_foo        (foo virtual table, new style with thunks)
2783
                _3foo$varname   (static data member)
2784
                _Q22rs2tu$vw    (static data member)
2785
                __t6vector1Zii  (constructor with template)
2786
                __thunk_4__$_7ostream (virtual function thunk)
2787
 */
2788
 
2789
static int
2790
gnu_special (struct work_stuff *work, const char **mangled, string *declp)
2791
{
2792
  int n;
2793
  int success = 1;
2794
  const char *p;
2795
 
2796
  if ((*mangled)[0] == '_'
2797
      && strchr (cplus_markers, (*mangled)[1]) != NULL
2798
      && (*mangled)[2] == '_')
2799
    {
2800
      /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2801
      (*mangled) += 3;
2802
      work -> destructor += 1;
2803
    }
2804
  else if ((*mangled)[0] == '_'
2805
           && (((*mangled)[1] == '_'
2806
                && (*mangled)[2] == 'v'
2807
                && (*mangled)[3] == 't'
2808
                && (*mangled)[4] == '_')
2809
               || ((*mangled)[1] == 'v'
2810
                   && (*mangled)[2] == 't'
2811
                   && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2812
    {
2813
      /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2814
         and create the decl.  Note that we consume the entire mangled
2815
         input string, which means that demangle_signature has no work
2816
         to do.  */
2817
      if ((*mangled)[2] == 'v')
2818
        (*mangled) += 5; /* New style, with thunks: "__vt_" */
2819
      else
2820
        (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2821
      while (**mangled != '\0')
2822
        {
2823
          switch (**mangled)
2824
            {
2825
            case 'Q':
2826
            case 'K':
2827
              success = demangle_qualified (work, mangled, declp, 0, 1);
2828
              break;
2829
            case 't':
2830
              success = demangle_template (work, mangled, declp, 0, 1,
2831
                                           1);
2832
              break;
2833
            default:
2834
              if (ISDIGIT((unsigned char)*mangled[0]))
2835
                {
2836
                  n = consume_count(mangled);
2837
                  /* We may be seeing a too-large size, or else a
2838
                     ".<digits>" indicating a static local symbol.  In
2839
                     any case, declare victory and move on; *don't* try
2840
                     to use n to allocate.  */
2841
                  if (n > (int) strlen (*mangled))
2842
                    {
2843
                      success = 1;
2844
                      break;
2845
                    }
2846
                }
2847
              else
2848
                {
2849
                  n = strcspn (*mangled, cplus_markers);
2850
                }
2851
              string_appendn (declp, *mangled, n);
2852
              (*mangled) += n;
2853
            }
2854
 
2855
          p = strpbrk (*mangled, cplus_markers);
2856
          if (success && ((p == NULL) || (p == *mangled)))
2857
            {
2858
              if (p != NULL)
2859
                {
2860
                  string_append (declp, SCOPE_STRING (work));
2861
                  (*mangled)++;
2862
                }
2863
            }
2864
          else
2865
            {
2866
              success = 0;
2867
              break;
2868
            }
2869
        }
2870
      if (success)
2871
        string_append (declp, " virtual table");
2872
    }
2873
  else if ((*mangled)[0] == '_'
2874
           && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2875
           && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2876
    {
2877
      /* static data member, "_3foo$varname" for example */
2878
      (*mangled)++;
2879
      switch (**mangled)
2880
        {
2881
        case 'Q':
2882
        case 'K':
2883
          success = demangle_qualified (work, mangled, declp, 0, 1);
2884
          break;
2885
        case 't':
2886
          success = demangle_template (work, mangled, declp, 0, 1, 1);
2887
          break;
2888
        default:
2889
          n = consume_count (mangled);
2890
          if (n < 0 || n > (long) strlen (*mangled))
2891
            {
2892
              success = 0;
2893
              break;
2894
            }
2895
 
2896
          if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2897
              && (*mangled)[9] == 'N'
2898
              && (*mangled)[8] == (*mangled)[10]
2899
              && strchr (cplus_markers, (*mangled)[8]))
2900
            {
2901
              /* A member of the anonymous namespace.  There's information
2902
                 about what identifier or filename it was keyed to, but
2903
                 it's just there to make the mangled name unique; we just
2904
                 step over it.  */
2905
              string_append (declp, "{anonymous}");
2906
              (*mangled) += n;
2907
 
2908
              /* Now p points to the marker before the N, so we need to
2909
                 update it to the first marker after what we consumed.  */
2910
              p = strpbrk (*mangled, cplus_markers);
2911
              break;
2912
            }
2913
 
2914
          string_appendn (declp, *mangled, n);
2915
          (*mangled) += n;
2916
        }
2917
      if (success && (p == *mangled))
2918
        {
2919
          /* Consumed everything up to the cplus_marker, append the
2920
             variable name.  */
2921
          (*mangled)++;
2922
          string_append (declp, SCOPE_STRING (work));
2923
          n = strlen (*mangled);
2924
          string_appendn (declp, *mangled, n);
2925
          (*mangled) += n;
2926
        }
2927
      else
2928
        {
2929
          success = 0;
2930
        }
2931
    }
2932
  else if (strncmp (*mangled, "__thunk_", 8) == 0)
2933
    {
2934
      int delta;
2935
 
2936
      (*mangled) += 8;
2937
      delta = consume_count (mangled);
2938
      if (delta == -1)
2939
        success = 0;
2940
      else
2941
        {
2942
          char *method = internal_cplus_demangle (work, ++*mangled);
2943
 
2944
          if (method)
2945
            {
2946
              char buf[50];
2947
              sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2948
              string_append (declp, buf);
2949
              string_append (declp, method);
2950
              free (method);
2951
              n = strlen (*mangled);
2952
              (*mangled) += n;
2953
            }
2954
          else
2955
            {
2956
              success = 0;
2957
            }
2958
        }
2959
    }
2960
  else if (strncmp (*mangled, "__t", 3) == 0
2961
           && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2962
    {
2963
      p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2964
      (*mangled) += 4;
2965
      switch (**mangled)
2966
        {
2967
        case 'Q':
2968
        case 'K':
2969
          success = demangle_qualified (work, mangled, declp, 0, 1);
2970
          break;
2971
        case 't':
2972
          success = demangle_template (work, mangled, declp, 0, 1, 1);
2973
          break;
2974
        default:
2975
          success = do_type (work, mangled, declp);
2976
          break;
2977
        }
2978
      if (success && **mangled != '\0')
2979
        success = 0;
2980
      if (success)
2981
        string_append (declp, p);
2982
    }
2983
  else
2984
    {
2985
      success = 0;
2986
    }
2987
  return (success);
2988
}
2989
 
2990
static void
2991
recursively_demangle(struct work_stuff *work, const char **mangled,
2992
                     string *result, int namelength)
2993
{
2994
  char * recurse = (char *)NULL;
2995
  char * recurse_dem = (char *)NULL;
2996
 
2997
  recurse = XNEWVEC (char, namelength + 1);
2998
  memcpy (recurse, *mangled, namelength);
2999
  recurse[namelength] = '\000';
3000
 
3001
  recurse_dem = cplus_demangle (recurse, work->options);
3002
 
3003
  if (recurse_dem)
3004
    {
3005
      string_append (result, recurse_dem);
3006
      free (recurse_dem);
3007
    }
3008
  else
3009
    {
3010
      string_appendn (result, *mangled, namelength);
3011
    }
3012
  free (recurse);
3013
  *mangled += namelength;
3014
}
3015
 
3016
/*
3017
 
3018
LOCAL FUNCTION
3019
 
3020
        arm_special -- special handling of ARM/lucid mangled strings
3021
 
3022
SYNOPSIS
3023
 
3024
        static int
3025
        arm_special (const char **mangled,
3026
                     string *declp);
3027
 
3028
 
3029
DESCRIPTION
3030
 
3031
        Process some special ARM style mangling forms that don't fit
3032
        the normal pattern.  For example:
3033
 
3034
                __vtbl__3foo            (foo virtual table)
3035
                __vtbl__3foo__3bar      (bar::foo virtual table)
3036
 
3037
 */
3038
 
3039
static int
3040
arm_special (const char **mangled, string *declp)
3041
{
3042
  int n;
3043
  int success = 1;
3044
  const char *scan;
3045
 
3046
  if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3047
    {
3048
      /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3049
         and create the decl.  Note that we consume the entire mangled
3050
         input string, which means that demangle_signature has no work
3051
         to do.  */
3052
      scan = *mangled + ARM_VTABLE_STRLEN;
3053
      while (*scan != '\0')        /* first check it can be demangled */
3054
        {
3055
          n = consume_count (&scan);
3056
          if (n == -1)
3057
            {
3058
              return (0);           /* no good */
3059
            }
3060
          scan += n;
3061
          if (scan[0] == '_' && scan[1] == '_')
3062
            {
3063
              scan += 2;
3064
            }
3065
        }
3066
      (*mangled) += ARM_VTABLE_STRLEN;
3067
      while (**mangled != '\0')
3068
        {
3069
          n = consume_count (mangled);
3070
          if (n == -1
3071
              || n > (long) strlen (*mangled))
3072
            return 0;
3073
          string_prependn (declp, *mangled, n);
3074
          (*mangled) += n;
3075
          if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3076
            {
3077
              string_prepend (declp, "::");
3078
              (*mangled) += 2;
3079
            }
3080
        }
3081
      string_append (declp, " virtual table");
3082
    }
3083
  else
3084
    {
3085
      success = 0;
3086
    }
3087
  return (success);
3088
}
3089
 
3090
/*
3091
 
3092
LOCAL FUNCTION
3093
 
3094
        demangle_qualified -- demangle 'Q' qualified name strings
3095
 
3096
SYNOPSIS
3097
 
3098
        static int
3099
        demangle_qualified (struct work_stuff *, const char *mangled,
3100
                            string *result, int isfuncname, int append);
3101
 
3102
DESCRIPTION
3103
 
3104
        Demangle a qualified name, such as "Q25Outer5Inner" which is
3105
        the mangled form of "Outer::Inner".  The demangled output is
3106
        prepended or appended to the result string according to the
3107
        state of the append flag.
3108
 
3109
        If isfuncname is nonzero, then the qualified name we are building
3110
        is going to be used as a member function name, so if it is a
3111
        constructor or destructor function, append an appropriate
3112
        constructor or destructor name.  I.E. for the above example,
3113
        the result for use as a constructor is "Outer::Inner::Inner"
3114
        and the result for use as a destructor is "Outer::Inner::~Inner".
3115
 
3116
BUGS
3117
 
3118
        Numeric conversion is ASCII dependent (FIXME).
3119
 
3120
 */
3121
 
3122
static int
3123
demangle_qualified (struct work_stuff *work, const char **mangled,
3124
                    string *result, int isfuncname, int append)
3125
{
3126
  int qualifiers = 0;
3127
  int success = 1;
3128
  char num[2];
3129
  string temp;
3130
  string last_name;
3131
  int bindex = register_Btype (work);
3132
 
3133
  /* We only make use of ISFUNCNAME if the entity is a constructor or
3134
     destructor.  */
3135
  isfuncname = (isfuncname
3136
                && ((work->constructor & 1) || (work->destructor & 1)));
3137
 
3138
  string_init (&temp);
3139
  string_init (&last_name);
3140
 
3141
  if ((*mangled)[0] == 'K')
3142
    {
3143
    /* Squangling qualified name reuse */
3144
      int idx;
3145
      (*mangled)++;
3146
      idx = consume_count_with_underscores (mangled);
3147
      if (idx == -1 || idx >= work -> numk)
3148
        success = 0;
3149
      else
3150
        string_append (&temp, work -> ktypevec[idx]);
3151
    }
3152
  else
3153
    switch ((*mangled)[1])
3154
    {
3155
    case '_':
3156
      /* GNU mangled name with more than 9 classes.  The count is preceded
3157
         by an underscore (to distinguish it from the <= 9 case) and followed
3158
         by an underscore.  */
3159
      (*mangled)++;
3160
      qualifiers = consume_count_with_underscores (mangled);
3161
      if (qualifiers == -1)
3162
        success = 0;
3163
      break;
3164
 
3165
    case '1':
3166
    case '2':
3167
    case '3':
3168
    case '4':
3169
    case '5':
3170
    case '6':
3171
    case '7':
3172
    case '8':
3173
    case '9':
3174
      /* The count is in a single digit.  */
3175
      num[0] = (*mangled)[1];
3176
      num[1] = '\0';
3177
      qualifiers = atoi (num);
3178
 
3179
      /* If there is an underscore after the digit, skip it.  This is
3180
         said to be for ARM-qualified names, but the ARM makes no
3181
         mention of such an underscore.  Perhaps cfront uses one.  */
3182
      if ((*mangled)[2] == '_')
3183
        {
3184
          (*mangled)++;
3185
        }
3186
      (*mangled) += 2;
3187
      break;
3188
 
3189
    case '0':
3190
    default:
3191
      success = 0;
3192
    }
3193
 
3194
  if (!success)
3195
    return success;
3196
 
3197
  /* Pick off the names and collect them in the temp buffer in the order
3198
     in which they are found, separated by '::'.  */
3199
 
3200
  while (qualifiers-- > 0)
3201
    {
3202
      int remember_K = 1;
3203
      string_clear (&last_name);
3204
 
3205
      if (*mangled[0] == '_')
3206
        (*mangled)++;
3207
 
3208
      if (*mangled[0] == 't')
3209
        {
3210
          /* Here we always append to TEMP since we will want to use
3211
             the template name without the template parameters as a
3212
             constructor or destructor name.  The appropriate
3213
             (parameter-less) value is returned by demangle_template
3214
             in LAST_NAME.  We do not remember the template type here,
3215
             in order to match the G++ mangling algorithm.  */
3216
          success = demangle_template(work, mangled, &temp,
3217
                                      &last_name, 1, 0);
3218
          if (!success)
3219
            break;
3220
        }
3221
      else if (*mangled[0] == 'K')
3222
        {
3223
          int idx;
3224
          (*mangled)++;
3225
          idx = consume_count_with_underscores (mangled);
3226
          if (idx == -1 || idx >= work->numk)
3227
            success = 0;
3228
          else
3229
            string_append (&temp, work->ktypevec[idx]);
3230
          remember_K = 0;
3231
 
3232
          if (!success) break;
3233
        }
3234
      else
3235
        {
3236
          if (EDG_DEMANGLING)
3237
            {
3238
              int namelength;
3239
              /* Now recursively demangle the qualifier
3240
               * This is necessary to deal with templates in
3241
               * mangling styles like EDG */
3242
              namelength = consume_count (mangled);
3243
              if (namelength == -1)
3244
                {
3245
                  success = 0;
3246
                  break;
3247
                }
3248
              recursively_demangle(work, mangled, &temp, namelength);
3249
            }
3250
          else
3251
            {
3252
              string_delete (&last_name);
3253
              success = do_type (work, mangled, &last_name);
3254
              if (!success)
3255
                break;
3256
              string_appends (&temp, &last_name);
3257
            }
3258
        }
3259
 
3260
      if (remember_K)
3261
        remember_Ktype (work, temp.b, LEN_STRING (&temp));
3262
 
3263
      if (qualifiers > 0)
3264
        string_append (&temp, SCOPE_STRING (work));
3265
    }
3266
 
3267
  remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3268
 
3269
  /* If we are using the result as a function name, we need to append
3270
     the appropriate '::' separated constructor or destructor name.
3271
     We do this here because this is the most convenient place, where
3272
     we already have a pointer to the name and the length of the name.  */
3273
 
3274
  if (isfuncname)
3275
    {
3276
      string_append (&temp, SCOPE_STRING (work));
3277
      if (work -> destructor & 1)
3278
        string_append (&temp, "~");
3279
      string_appends (&temp, &last_name);
3280
    }
3281
 
3282
  /* Now either prepend the temp buffer to the result, or append it,
3283
     depending upon the state of the append flag.  */
3284
 
3285
  if (append)
3286
    string_appends (result, &temp);
3287
  else
3288
    {
3289
      if (!STRING_EMPTY (result))
3290
        string_append (&temp, SCOPE_STRING (work));
3291
      string_prepends (result, &temp);
3292
    }
3293
 
3294
  string_delete (&last_name);
3295
  string_delete (&temp);
3296
  return (success);
3297
}
3298
 
3299
/*
3300
 
3301
LOCAL FUNCTION
3302
 
3303
        get_count -- convert an ascii count to integer, consuming tokens
3304
 
3305
SYNOPSIS
3306
 
3307
        static int
3308
        get_count (const char **type, int *count)
3309
 
3310
DESCRIPTION
3311
 
3312
        Assume that *type points at a count in a mangled name; set
3313
        *count to its value, and set *type to the next character after
3314
        the count.  There are some weird rules in effect here.
3315
 
3316
        If *type does not point at a string of digits, return zero.
3317
 
3318
        If *type points at a string of digits followed by an
3319
        underscore, set *count to their value as an integer, advance
3320
        *type to point *after the underscore, and return 1.
3321
 
3322
        If *type points at a string of digits not followed by an
3323
        underscore, consume only the first digit.  Set *count to its
3324
        value as an integer, leave *type pointing after that digit,
3325
        and return 1.
3326
 
3327
        The excuse for this odd behavior: in the ARM and HP demangling
3328
        styles, a type can be followed by a repeat count of the form
3329
        `Nxy', where:
3330
 
3331
        `x' is a single digit specifying how many additional copies
3332
            of the type to append to the argument list, and
3333
 
3334
        `y' is one or more digits, specifying the zero-based index of
3335
            the first repeated argument in the list.  Yes, as you're
3336
            unmangling the name you can figure this out yourself, but
3337
            it's there anyway.
3338
 
3339
        So, for example, in `bar__3fooFPiN51', the first argument is a
3340
        pointer to an integer (`Pi'), and then the next five arguments
3341
        are the same (`N5'), and the first repeat is the function's
3342
        second argument (`1').
3343
*/
3344
 
3345
static int
3346
get_count (const char **type, int *count)
3347
{
3348
  const char *p;
3349
  int n;
3350
 
3351
  if (!ISDIGIT ((unsigned char)**type))
3352
    return (0);
3353
  else
3354
    {
3355
      *count = **type - '0';
3356
      (*type)++;
3357
      if (ISDIGIT ((unsigned char)**type))
3358
        {
3359
          p = *type;
3360
          n = *count;
3361
          do
3362
            {
3363
              n *= 10;
3364
              n += *p - '0';
3365
              p++;
3366
            }
3367
          while (ISDIGIT ((unsigned char)*p));
3368
          if (*p == '_')
3369
            {
3370
              *type = p + 1;
3371
              *count = n;
3372
            }
3373
        }
3374
    }
3375
  return (1);
3376
}
3377
 
3378
/* RESULT will be initialised here; it will be freed on failure.  The
3379
   value returned is really a type_kind_t.  */
3380
 
3381
static int
3382
do_type (struct work_stuff *work, const char **mangled, string *result)
3383
{
3384
  int n;
3385
  int done;
3386
  int success;
3387
  string decl;
3388
  const char *remembered_type;
3389
  int type_quals;
3390
  type_kind_t tk = tk_none;
3391
 
3392
  string_init (&decl);
3393
  string_init (result);
3394
 
3395
  done = 0;
3396
  success = 1;
3397
  while (success && !done)
3398
    {
3399
      int member;
3400
      switch (**mangled)
3401
        {
3402
 
3403
          /* A pointer type */
3404
        case 'P':
3405
        case 'p':
3406
          (*mangled)++;
3407
          if (! (work -> options & DMGL_JAVA))
3408
            string_prepend (&decl, "*");
3409
          if (tk == tk_none)
3410
            tk = tk_pointer;
3411
          break;
3412
 
3413
          /* A reference type */
3414
        case 'R':
3415
          (*mangled)++;
3416
          string_prepend (&decl, "&");
3417
          if (tk == tk_none)
3418
            tk = tk_reference;
3419
          break;
3420
 
3421
          /* An array */
3422
        case 'A':
3423
          {
3424
            ++(*mangled);
3425
            if (!STRING_EMPTY (&decl)
3426
                && (decl.b[0] == '*' || decl.b[0] == '&'))
3427
              {
3428
                string_prepend (&decl, "(");
3429
                string_append (&decl, ")");
3430
              }
3431
            string_append (&decl, "[");
3432
            if (**mangled != '_')
3433
              success = demangle_template_value_parm (work, mangled, &decl,
3434
                                                      tk_integral);
3435
            if (**mangled == '_')
3436
              ++(*mangled);
3437
            string_append (&decl, "]");
3438
            break;
3439
          }
3440
 
3441
        /* A back reference to a previously seen type */
3442
        case 'T':
3443
          (*mangled)++;
3444
          if (!get_count (mangled, &n) || n >= work -> ntypes)
3445
            {
3446
              success = 0;
3447
            }
3448
          else
3449
            {
3450
              remembered_type = work -> typevec[n];
3451
              mangled = &remembered_type;
3452
            }
3453
          break;
3454
 
3455
          /* A function */
3456
        case 'F':
3457
          (*mangled)++;
3458
            if (!STRING_EMPTY (&decl)
3459
                && (decl.b[0] == '*' || decl.b[0] == '&'))
3460
            {
3461
              string_prepend (&decl, "(");
3462
              string_append (&decl, ")");
3463
            }
3464
          /* After picking off the function args, we expect to either find the
3465
             function return type (preceded by an '_') or the end of the
3466
             string.  */
3467
          if (!demangle_nested_args (work, mangled, &decl)
3468
              || (**mangled != '_' && **mangled != '\0'))
3469
            {
3470
              success = 0;
3471
              break;
3472
            }
3473
          if (success && (**mangled == '_'))
3474
            (*mangled)++;
3475
          break;
3476
 
3477
        case 'M':
3478
        case 'O':
3479
          {
3480
            type_quals = TYPE_UNQUALIFIED;
3481
 
3482
            member = **mangled == 'M';
3483
            (*mangled)++;
3484
 
3485
            string_append (&decl, ")");
3486
 
3487
            /* We don't need to prepend `::' for a qualified name;
3488
               demangle_qualified will do that for us.  */
3489
            if (**mangled != 'Q')
3490
              string_prepend (&decl, SCOPE_STRING (work));
3491
 
3492
            if (ISDIGIT ((unsigned char)**mangled))
3493
              {
3494
                n = consume_count (mangled);
3495
                if (n == -1
3496
                    || (int) strlen (*mangled) < n)
3497
                  {
3498
                    success = 0;
3499
                    break;
3500
                  }
3501
                string_prependn (&decl, *mangled, n);
3502
                *mangled += n;
3503
              }
3504
            else if (**mangled == 'X' || **mangled == 'Y')
3505
              {
3506
                string temp;
3507
                do_type (work, mangled, &temp);
3508
                string_prepends (&decl, &temp);
3509
                string_delete (&temp);
3510
              }
3511
            else if (**mangled == 't')
3512
              {
3513
                string temp;
3514
                string_init (&temp);
3515
                success = demangle_template (work, mangled, &temp,
3516
                                             NULL, 1, 1);
3517
                if (success)
3518
                  {
3519
                    string_prependn (&decl, temp.b, temp.p - temp.b);
3520
                    string_delete (&temp);
3521
                  }
3522
                else
3523
                  break;
3524
              }
3525
            else if (**mangled == 'Q')
3526
              {
3527
                success = demangle_qualified (work, mangled, &decl,
3528
                                              /*isfuncnam=*/0,
3529
                                              /*append=*/0);
3530
                if (!success)
3531
                  break;
3532
              }
3533
            else
3534
              {
3535
                success = 0;
3536
                break;
3537
              }
3538
 
3539
            string_prepend (&decl, "(");
3540
            if (member)
3541
              {
3542
                switch (**mangled)
3543
                  {
3544
                  case 'C':
3545
                  case 'V':
3546
                  case 'u':
3547
                    type_quals |= code_for_qualifier (**mangled);
3548
                    (*mangled)++;
3549
                    break;
3550
 
3551
                  default:
3552
                    break;
3553
                  }
3554
 
3555
                if (*(*mangled)++ != 'F')
3556
                  {
3557
                    success = 0;
3558
                    break;
3559
                  }
3560
              }
3561
            if ((member && !demangle_nested_args (work, mangled, &decl))
3562
                || **mangled != '_')
3563
              {
3564
                success = 0;
3565
                break;
3566
              }
3567
            (*mangled)++;
3568
            if (! PRINT_ANSI_QUALIFIERS)
3569
              {
3570
                break;
3571
              }
3572
            if (type_quals != TYPE_UNQUALIFIED)
3573
              {
3574
                APPEND_BLANK (&decl);
3575
                string_append (&decl, qualifier_string (type_quals));
3576
              }
3577
            break;
3578
          }
3579
        case 'G':
3580
          (*mangled)++;
3581
          break;
3582
 
3583
        case 'C':
3584
        case 'V':
3585
        case 'u':
3586
          if (PRINT_ANSI_QUALIFIERS)
3587
            {
3588
              if (!STRING_EMPTY (&decl))
3589
                string_prepend (&decl, " ");
3590
 
3591
              string_prepend (&decl, demangle_qualifier (**mangled));
3592
            }
3593
          (*mangled)++;
3594
          break;
3595
          /*
3596
            }
3597
            */
3598
 
3599
          /* fall through */
3600
        default:
3601
          done = 1;
3602
          break;
3603
        }
3604
    }
3605
 
3606
  if (success) switch (**mangled)
3607
    {
3608
      /* A qualified name, such as "Outer::Inner".  */
3609
    case 'Q':
3610
    case 'K':
3611
      {
3612
        success = demangle_qualified (work, mangled, result, 0, 1);
3613
        break;
3614
      }
3615
 
3616
    /* A back reference to a previously seen squangled type */
3617
    case 'B':
3618
      (*mangled)++;
3619
      if (!get_count (mangled, &n) || n >= work -> numb)
3620
        success = 0;
3621
      else
3622
        string_append (result, work->btypevec[n]);
3623
      break;
3624
 
3625
    case 'X':
3626
    case 'Y':
3627
      /* A template parm.  We substitute the corresponding argument. */
3628
      {
3629
        int idx;
3630
 
3631
        (*mangled)++;
3632
        idx = consume_count_with_underscores (mangled);
3633
 
3634
        if (idx == -1
3635
            || (work->tmpl_argvec && idx >= work->ntmpl_args)
3636
            || consume_count_with_underscores (mangled) == -1)
3637
          {
3638
            success = 0;
3639
            break;
3640
          }
3641
 
3642
        if (work->tmpl_argvec)
3643
          string_append (result, work->tmpl_argvec[idx]);
3644
        else
3645
          string_append_template_idx (result, idx);
3646
 
3647
        success = 1;
3648
      }
3649
    break;
3650
 
3651
    default:
3652
      success = demangle_fund_type (work, mangled, result);
3653
      if (tk == tk_none)
3654
        tk = (type_kind_t) success;
3655
      break;
3656
    }
3657
 
3658
  if (success)
3659
    {
3660
      if (!STRING_EMPTY (&decl))
3661
        {
3662
          string_append (result, " ");
3663
          string_appends (result, &decl);
3664
        }
3665
    }
3666
  else
3667
    string_delete (result);
3668
  string_delete (&decl);
3669
 
3670
  if (success)
3671
    /* Assume an integral type, if we're not sure.  */
3672
    return (int) ((tk == tk_none) ? tk_integral : tk);
3673
  else
3674
    return 0;
3675
}
3676
 
3677
/* Given a pointer to a type string that represents a fundamental type
3678
   argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3679
   string in which the demangled output is being built in RESULT, and
3680
   the WORK structure, decode the types and add them to the result.
3681
 
3682
   For example:
3683
 
3684
        "Ci"    =>      "const int"
3685
        "Sl"    =>      "signed long"
3686
        "CUs"   =>      "const unsigned short"
3687
 
3688
   The value returned is really a type_kind_t.  */
3689
 
3690
static int
3691
demangle_fund_type (struct work_stuff *work,
3692
                    const char **mangled, string *result)
3693
{
3694
  int done = 0;
3695
  int success = 1;
3696
  char buf[INTBUF_SIZE + 5 /* 'int%u_t' */];
3697
  unsigned int dec = 0;
3698
  type_kind_t tk = tk_integral;
3699
 
3700
  /* First pick off any type qualifiers.  There can be more than one.  */
3701
 
3702
  while (!done)
3703
    {
3704
      switch (**mangled)
3705
        {
3706
        case 'C':
3707
        case 'V':
3708
        case 'u':
3709
          if (PRINT_ANSI_QUALIFIERS)
3710
            {
3711
              if (!STRING_EMPTY (result))
3712
                string_prepend (result, " ");
3713
              string_prepend (result, demangle_qualifier (**mangled));
3714
            }
3715
          (*mangled)++;
3716
          break;
3717
        case 'U':
3718
          (*mangled)++;
3719
          APPEND_BLANK (result);
3720
          string_append (result, "unsigned");
3721
          break;
3722
        case 'S': /* signed char only */
3723
          (*mangled)++;
3724
          APPEND_BLANK (result);
3725
          string_append (result, "signed");
3726
          break;
3727
        case 'J':
3728
          (*mangled)++;
3729
          APPEND_BLANK (result);
3730
          string_append (result, "__complex");
3731
          break;
3732
        default:
3733
          done = 1;
3734
          break;
3735
        }
3736
    }
3737
 
3738
  /* Now pick off the fundamental type.  There can be only one.  */
3739
 
3740
  switch (**mangled)
3741
    {
3742
    case '\0':
3743
    case '_':
3744
      break;
3745
    case 'v':
3746
      (*mangled)++;
3747
      APPEND_BLANK (result);
3748
      string_append (result, "void");
3749
      break;
3750
    case 'x':
3751
      (*mangled)++;
3752
      APPEND_BLANK (result);
3753
      string_append (result, "long long");
3754
      break;
3755
    case 'l':
3756
      (*mangled)++;
3757
      APPEND_BLANK (result);
3758
      string_append (result, "long");
3759
      break;
3760
    case 'i':
3761
      (*mangled)++;
3762
      APPEND_BLANK (result);
3763
      string_append (result, "int");
3764
      break;
3765
    case 's':
3766
      (*mangled)++;
3767
      APPEND_BLANK (result);
3768
      string_append (result, "short");
3769
      break;
3770
    case 'b':
3771
      (*mangled)++;
3772
      APPEND_BLANK (result);
3773
      string_append (result, "bool");
3774
      tk = tk_bool;
3775
      break;
3776
    case 'c':
3777
      (*mangled)++;
3778
      APPEND_BLANK (result);
3779
      string_append (result, "char");
3780
      tk = tk_char;
3781
      break;
3782
    case 'w':
3783
      (*mangled)++;
3784
      APPEND_BLANK (result);
3785
      string_append (result, "wchar_t");
3786
      tk = tk_char;
3787
      break;
3788
    case 'r':
3789
      (*mangled)++;
3790
      APPEND_BLANK (result);
3791
      string_append (result, "long double");
3792
      tk = tk_real;
3793
      break;
3794
    case 'd':
3795
      (*mangled)++;
3796
      APPEND_BLANK (result);
3797
      string_append (result, "double");
3798
      tk = tk_real;
3799
      break;
3800
    case 'f':
3801
      (*mangled)++;
3802
      APPEND_BLANK (result);
3803
      string_append (result, "float");
3804
      tk = tk_real;
3805
      break;
3806
    case 'G':
3807
      (*mangled)++;
3808
      if (!ISDIGIT ((unsigned char)**mangled))
3809
        {
3810
          success = 0;
3811
          break;
3812
        }
3813
    case 'I':
3814
      (*mangled)++;
3815
      if (**mangled == '_')
3816
        {
3817
          int i;
3818
          (*mangled)++;
3819
          for (i = 0;
3820
               i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3821
               (*mangled)++, i++)
3822
            buf[i] = **mangled;
3823
          if (**mangled != '_')
3824
            {
3825
              success = 0;
3826
              break;
3827
            }
3828
          buf[i] = '\0';
3829
          (*mangled)++;
3830
        }
3831
      else
3832
        {
3833
          strncpy (buf, *mangled, 2);
3834
          buf[2] = '\0';
3835
          *mangled += min (strlen (*mangled), 2);
3836
        }
3837
      sscanf (buf, "%x", &dec);
3838
      sprintf (buf, "int%u_t", dec);
3839
      APPEND_BLANK (result);
3840
      string_append (result, buf);
3841
      break;
3842
 
3843
      /* fall through */
3844
      /* An explicit type, such as "6mytype" or "7integer" */
3845
    case '0':
3846
    case '1':
3847
    case '2':
3848
    case '3':
3849
    case '4':
3850
    case '5':
3851
    case '6':
3852
    case '7':
3853
    case '8':
3854
    case '9':
3855
      {
3856
        int bindex = register_Btype (work);
3857
        string btype;
3858
        string_init (&btype);
3859
        if (demangle_class_name (work, mangled, &btype)) {
3860
          remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3861
          APPEND_BLANK (result);
3862
          string_appends (result, &btype);
3863
        }
3864
        else
3865
          success = 0;
3866
        string_delete (&btype);
3867
        break;
3868
      }
3869
    case 't':
3870
      {
3871
        string btype;
3872
        string_init (&btype);
3873
        success = demangle_template (work, mangled, &btype, 0, 1, 1);
3874
        string_appends (result, &btype);
3875
        string_delete (&btype);
3876
        break;
3877
      }
3878
    default:
3879
      success = 0;
3880
      break;
3881
    }
3882
 
3883
  return success ? ((int) tk) : 0;
3884
}
3885
 
3886
 
3887
/* Handle a template's value parameter for HP aCC (extension from ARM)
3888
   **mangled points to 'S' or 'U' */
3889
 
3890
static int
3891
do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED,
3892
                               const char **mangled, string *result)
3893
{
3894
  int unsigned_const;
3895
 
3896
  if (**mangled != 'U' && **mangled != 'S')
3897
    return 0;
3898
 
3899
  unsigned_const = (**mangled == 'U');
3900
 
3901
  (*mangled)++;
3902
 
3903
  switch (**mangled)
3904
    {
3905
      case 'N':
3906
        string_append (result, "-");
3907
        /* fall through */
3908
      case 'P':
3909
        (*mangled)++;
3910
        break;
3911
      case 'M':
3912
        /* special case for -2^31 */
3913
        string_append (result, "-2147483648");
3914
        (*mangled)++;
3915
        return 1;
3916
      default:
3917
        return 0;
3918
    }
3919
 
3920
  /* We have to be looking at an integer now */
3921
  if (!(ISDIGIT ((unsigned char)**mangled)))
3922
    return 0;
3923
 
3924
  /* We only deal with integral values for template
3925
     parameters -- so it's OK to look only for digits */
3926
  while (ISDIGIT ((unsigned char)**mangled))
3927
    {
3928
      char_str[0] = **mangled;
3929
      string_append (result, char_str);
3930
      (*mangled)++;
3931
    }
3932
 
3933
  if (unsigned_const)
3934
    string_append (result, "U");
3935
 
3936
  /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3937
     with L or LL suffixes. pai/1997-09-03 */
3938
 
3939
  return 1; /* success */
3940
}
3941
 
3942
/* Handle a template's literal parameter for HP aCC (extension from ARM)
3943
   **mangled is pointing to the 'A' */
3944
 
3945
static int
3946
do_hpacc_template_literal (struct work_stuff *work, const char **mangled,
3947
                           string *result)
3948
{
3949
  int literal_len = 0;
3950
  char * recurse;
3951
  char * recurse_dem;
3952
 
3953
  if (**mangled != 'A')
3954
    return 0;
3955
 
3956
  (*mangled)++;
3957
 
3958
  literal_len = consume_count (mangled);
3959
 
3960
  if (literal_len <= 0)
3961
    return 0;
3962
 
3963
  /* Literal parameters are names of arrays, functions, etc.  and the
3964
     canonical representation uses the address operator */
3965
  string_append (result, "&");
3966
 
3967
  /* Now recursively demangle the literal name */
3968
  recurse = XNEWVEC (char, literal_len + 1);
3969
  memcpy (recurse, *mangled, literal_len);
3970
  recurse[literal_len] = '\000';
3971
 
3972
  recurse_dem = cplus_demangle (recurse, work->options);
3973
 
3974
  if (recurse_dem)
3975
    {
3976
      string_append (result, recurse_dem);
3977
      free (recurse_dem);
3978
    }
3979
  else
3980
    {
3981
      string_appendn (result, *mangled, literal_len);
3982
    }
3983
  (*mangled) += literal_len;
3984
  free (recurse);
3985
 
3986
  return 1;
3987
}
3988
 
3989
static int
3990
snarf_numeric_literal (const char **args, string *arg)
3991
{
3992
  if (**args == '-')
3993
    {
3994
      char_str[0] = '-';
3995
      string_append (arg, char_str);
3996
      (*args)++;
3997
    }
3998
  else if (**args == '+')
3999
    (*args)++;
4000
 
4001
  if (!ISDIGIT ((unsigned char)**args))
4002
    return 0;
4003
 
4004
  while (ISDIGIT ((unsigned char)**args))
4005
    {
4006
      char_str[0] = **args;
4007
      string_append (arg, char_str);
4008
      (*args)++;
4009
    }
4010
 
4011
  return 1;
4012
}
4013
 
4014
/* Demangle the next argument, given by MANGLED into RESULT, which
4015
   *should be an uninitialized* string.  It will be initialized here,
4016
   and free'd should anything go wrong.  */
4017
 
4018
static int
4019
do_arg (struct work_stuff *work, const char **mangled, string *result)
4020
{
4021
  /* Remember where we started so that we can record the type, for
4022
     non-squangling type remembering.  */
4023
  const char *start = *mangled;
4024
 
4025
  string_init (result);
4026
 
4027
  if (work->nrepeats > 0)
4028
    {
4029
      --work->nrepeats;
4030
 
4031
      if (work->previous_argument == 0)
4032
        return 0;
4033
 
4034
      /* We want to reissue the previous type in this argument list.  */
4035
      string_appends (result, work->previous_argument);
4036
      return 1;
4037
    }
4038
 
4039
  if (**mangled == 'n')
4040
    {
4041
      /* A squangling-style repeat.  */
4042
      (*mangled)++;
4043
      work->nrepeats = consume_count(mangled);
4044
 
4045
      if (work->nrepeats <= 0)
4046
        /* This was not a repeat count after all.  */
4047
        return 0;
4048
 
4049
      if (work->nrepeats > 9)
4050
        {
4051
          if (**mangled != '_')
4052
            /* The repeat count should be followed by an '_' in this
4053
               case.  */
4054
            return 0;
4055
          else
4056
            (*mangled)++;
4057
        }
4058
 
4059
      /* Now, the repeat is all set up.  */
4060
      return do_arg (work, mangled, result);
4061
    }
4062
 
4063
  /* Save the result in WORK->previous_argument so that we can find it
4064
     if it's repeated.  Note that saving START is not good enough: we
4065
     do not want to add additional types to the back-referenceable
4066
     type vector when processing a repeated type.  */
4067
  if (work->previous_argument)
4068
    string_delete (work->previous_argument);
4069
  else
4070
    work->previous_argument = XNEW (string);
4071
 
4072
  if (!do_type (work, mangled, work->previous_argument))
4073
    return 0;
4074
 
4075
  string_appends (result, work->previous_argument);
4076
 
4077
  remember_type (work, start, *mangled - start);
4078
  return 1;
4079
}
4080
 
4081
static void
4082
remember_type (struct work_stuff *work, const char *start, int len)
4083
{
4084
  char *tem;
4085
 
4086
  if (work->forgetting_types)
4087
    return;
4088
 
4089
  if (work -> ntypes >= work -> typevec_size)
4090
    {
4091
      if (work -> typevec_size == 0)
4092
        {
4093
          work -> typevec_size = 3;
4094
          work -> typevec = XNEWVEC (char *, work->typevec_size);
4095
        }
4096
      else
4097
        {
4098
          work -> typevec_size *= 2;
4099
          work -> typevec
4100
            = XRESIZEVEC (char *, work->typevec, work->typevec_size);
4101
        }
4102
    }
4103
  tem = XNEWVEC (char, len + 1);
4104
  memcpy (tem, start, len);
4105
  tem[len] = '\0';
4106
  work -> typevec[work -> ntypes++] = tem;
4107
}
4108
 
4109
 
4110
/* Remember a K type class qualifier. */
4111
static void
4112
remember_Ktype (struct work_stuff *work, const char *start, int len)
4113
{
4114
  char *tem;
4115
 
4116
  if (work -> numk >= work -> ksize)
4117
    {
4118
      if (work -> ksize == 0)
4119
        {
4120
          work -> ksize = 5;
4121
          work -> ktypevec = XNEWVEC (char *, work->ksize);
4122
        }
4123
      else
4124
        {
4125
          work -> ksize *= 2;
4126
          work -> ktypevec
4127
            = XRESIZEVEC (char *, work->ktypevec, work->ksize);
4128
        }
4129
    }
4130
  tem = XNEWVEC (char, len + 1);
4131
  memcpy (tem, start, len);
4132
  tem[len] = '\0';
4133
  work -> ktypevec[work -> numk++] = tem;
4134
}
4135
 
4136
/* Register a B code, and get an index for it. B codes are registered
4137
   as they are seen, rather than as they are completed, so map<temp<char> >
4138
   registers map<temp<char> > as B0, and temp<char> as B1 */
4139
 
4140
static int
4141
register_Btype (struct work_stuff *work)
4142
{
4143
  int ret;
4144
 
4145
  if (work -> numb >= work -> bsize)
4146
    {
4147
      if (work -> bsize == 0)
4148
        {
4149
          work -> bsize = 5;
4150
          work -> btypevec = XNEWVEC (char *, work->bsize);
4151
        }
4152
      else
4153
        {
4154
          work -> bsize *= 2;
4155
          work -> btypevec
4156
            = XRESIZEVEC (char *, work->btypevec, work->bsize);
4157
        }
4158
    }
4159
  ret = work -> numb++;
4160
  work -> btypevec[ret] = NULL;
4161
  return(ret);
4162
}
4163
 
4164
/* Store a value into a previously registered B code type. */
4165
 
4166
static void
4167
remember_Btype (struct work_stuff *work, const char *start,
4168
                int len, int index)
4169
{
4170
  char *tem;
4171
 
4172
  tem = XNEWVEC (char, len + 1);
4173
  memcpy (tem, start, len);
4174
  tem[len] = '\0';
4175
  work -> btypevec[index] = tem;
4176
}
4177
 
4178
/* Lose all the info related to B and K type codes. */
4179
static void
4180
forget_B_and_K_types (struct work_stuff *work)
4181
{
4182
  int i;
4183
 
4184
  while (work -> numk > 0)
4185
    {
4186
      i = --(work -> numk);
4187
      if (work -> ktypevec[i] != NULL)
4188
        {
4189
          free (work -> ktypevec[i]);
4190
          work -> ktypevec[i] = NULL;
4191
        }
4192
    }
4193
 
4194
  while (work -> numb > 0)
4195
    {
4196
      i = --(work -> numb);
4197
      if (work -> btypevec[i] != NULL)
4198
        {
4199
          free (work -> btypevec[i]);
4200
          work -> btypevec[i] = NULL;
4201
        }
4202
    }
4203
}
4204
/* Forget the remembered types, but not the type vector itself.  */
4205
 
4206
static void
4207
forget_types (struct work_stuff *work)
4208
{
4209
  int i;
4210
 
4211
  while (work -> ntypes > 0)
4212
    {
4213
      i = --(work -> ntypes);
4214
      if (work -> typevec[i] != NULL)
4215
        {
4216
          free (work -> typevec[i]);
4217
          work -> typevec[i] = NULL;
4218
        }
4219
    }
4220
}
4221
 
4222
/* Process the argument list part of the signature, after any class spec
4223
   has been consumed, as well as the first 'F' character (if any).  For
4224
   example:
4225
 
4226
   "__als__3fooRT0"             =>      process "RT0"
4227
   "complexfunc5__FPFPc_PFl_i"  =>      process "PFPc_PFl_i"
4228
 
4229
   DECLP must be already initialised, usually non-empty.  It won't be freed
4230
   on failure.
4231
 
4232
   Note that g++ differs significantly from ARM and lucid style mangling
4233
   with regards to references to previously seen types.  For example, given
4234
   the source fragment:
4235
 
4236
     class foo {
4237
       public:
4238
       foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4239
     };
4240
 
4241
     foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4242
     void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4243
 
4244
   g++ produces the names:
4245
 
4246
     __3fooiRT0iT2iT2
4247
     foo__FiR3fooiT1iT1
4248
 
4249
   while lcc (and presumably other ARM style compilers as well) produces:
4250
 
4251
     foo__FiR3fooT1T2T1T2
4252
     __ct__3fooFiR3fooT1T2T1T2
4253
 
4254
   Note that g++ bases its type numbers starting at zero and counts all
4255
   previously seen types, while lucid/ARM bases its type numbers starting
4256
   at one and only considers types after it has seen the 'F' character
4257
   indicating the start of the function args.  For lucid/ARM style, we
4258
   account for this difference by discarding any previously seen types when
4259
   we see the 'F' character, and subtracting one from the type number
4260
   reference.
4261
 
4262
 */
4263
 
4264
static int
4265
demangle_args (struct work_stuff *work, const char **mangled,
4266
               string *declp)
4267
{
4268
  string arg;
4269
  int need_comma = 0;
4270
  int r;
4271
  int t;
4272
  const char *tem;
4273
  char temptype;
4274
 
4275
  if (PRINT_ARG_TYPES)
4276
    {
4277
      string_append (declp, "(");
4278
      if (**mangled == '\0')
4279
        {
4280
          string_append (declp, "void");
4281
        }
4282
    }
4283
 
4284
  while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4285
         || work->nrepeats > 0)
4286
    {
4287
      if ((**mangled == 'N') || (**mangled == 'T'))
4288
        {
4289
          temptype = *(*mangled)++;
4290
 
4291
          if (temptype == 'N')
4292
            {
4293
              if (!get_count (mangled, &r))
4294
                {
4295
                  return (0);
4296
                }
4297
            }
4298
          else
4299
            {
4300
              r = 1;
4301
            }
4302
          if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4303
            {
4304
              /* If we have 10 or more types we might have more than a 1 digit
4305
                 index so we'll have to consume the whole count here. This
4306
                 will lose if the next thing is a type name preceded by a
4307
                 count but it's impossible to demangle that case properly
4308
                 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4309
                 Pc, ...)"  or "(..., type12, char *, ...)" */
4310
              if ((t = consume_count(mangled)) <= 0)
4311
                {
4312
                  return (0);
4313
                }
4314
            }
4315
          else
4316
            {
4317
              if (!get_count (mangled, &t))
4318
                {
4319
                  return (0);
4320
                }
4321
            }
4322
          if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4323
            {
4324
              t--;
4325
            }
4326
          /* Validate the type index.  Protect against illegal indices from
4327
             malformed type strings.  */
4328
          if ((t < 0) || (t >= work -> ntypes))
4329
            {
4330
              return (0);
4331
            }
4332
          while (work->nrepeats > 0 || --r >= 0)
4333
            {
4334
              tem = work -> typevec[t];
4335
              if (need_comma && PRINT_ARG_TYPES)
4336
                {
4337
                  string_append (declp, ", ");
4338
                }
4339
              if (!do_arg (work, &tem, &arg))
4340
                {
4341
                  return (0);
4342
                }
4343
              if (PRINT_ARG_TYPES)
4344
                {
4345
                  string_appends (declp, &arg);
4346
                }
4347
              string_delete (&arg);
4348
              need_comma = 1;
4349
            }
4350
        }
4351
      else
4352
        {
4353
          if (need_comma && PRINT_ARG_TYPES)
4354
            string_append (declp, ", ");
4355
          if (!do_arg (work, mangled, &arg))
4356
            return (0);
4357
          if (PRINT_ARG_TYPES)
4358
            string_appends (declp, &arg);
4359
          string_delete (&arg);
4360
          need_comma = 1;
4361
        }
4362
    }
4363
 
4364
  if (**mangled == 'e')
4365
    {
4366
      (*mangled)++;
4367
      if (PRINT_ARG_TYPES)
4368
        {
4369
          if (need_comma)
4370
            {
4371
              string_append (declp, ",");
4372
            }
4373
          string_append (declp, "...");
4374
        }
4375
    }
4376
 
4377
  if (PRINT_ARG_TYPES)
4378
    {
4379
      string_append (declp, ")");
4380
    }
4381
  return (1);
4382
}
4383
 
4384
/* Like demangle_args, but for demangling the argument lists of function
4385
   and method pointers or references, not top-level declarations.  */
4386
 
4387
static int
4388
demangle_nested_args (struct work_stuff *work, const char **mangled,
4389
                      string *declp)
4390
{
4391
  string* saved_previous_argument;
4392
  int result;
4393
  int saved_nrepeats;
4394
 
4395
  /* The G++ name-mangling algorithm does not remember types on nested
4396
     argument lists, unless -fsquangling is used, and in that case the
4397
     type vector updated by remember_type is not used.  So, we turn
4398
     off remembering of types here.  */
4399
  ++work->forgetting_types;
4400
 
4401
  /* For the repeat codes used with -fsquangling, we must keep track of
4402
     the last argument.  */
4403
  saved_previous_argument = work->previous_argument;
4404
  saved_nrepeats = work->nrepeats;
4405
  work->previous_argument = 0;
4406
  work->nrepeats = 0;
4407
 
4408
  /* Actually demangle the arguments.  */
4409
  result = demangle_args (work, mangled, declp);
4410
 
4411
  /* Restore the previous_argument field.  */
4412
  if (work->previous_argument)
4413
    {
4414
      string_delete (work->previous_argument);
4415
      free ((char *) work->previous_argument);
4416
    }
4417
  work->previous_argument = saved_previous_argument;
4418
  --work->forgetting_types;
4419
  work->nrepeats = saved_nrepeats;
4420
 
4421
  return result;
4422
}
4423
 
4424
static void
4425
demangle_function_name (struct work_stuff *work, const char **mangled,
4426
                        string *declp, const char *scan)
4427
{
4428
  size_t i;
4429
  string type;
4430
  const char *tem;
4431
 
4432
  string_appendn (declp, (*mangled), scan - (*mangled));
4433
  string_need (declp, 1);
4434
  *(declp -> p) = '\0';
4435
 
4436
  /* Consume the function name, including the "__" separating the name
4437
     from the signature.  We are guaranteed that SCAN points to the
4438
     separator.  */
4439
 
4440
  (*mangled) = scan + 2;
4441
  /* We may be looking at an instantiation of a template function:
4442
     foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4443
     following _F marks the start of the function arguments.  Handle
4444
     the template arguments first. */
4445
 
4446
  if (HP_DEMANGLING && (**mangled == 'X'))
4447
    {
4448
      demangle_arm_hp_template (work, mangled, 0, declp);
4449
      /* This leaves MANGLED pointing to the 'F' marking func args */
4450
    }
4451
 
4452
  if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4453
    {
4454
 
4455
      /* See if we have an ARM style constructor or destructor operator.
4456
         If so, then just record it, clear the decl, and return.
4457
         We can't build the actual constructor/destructor decl until later,
4458
         when we recover the class name from the signature.  */
4459
 
4460
      if (strcmp (declp -> b, "__ct") == 0)
4461
        {
4462
          work -> constructor += 1;
4463
          string_clear (declp);
4464
          return;
4465
        }
4466
      else if (strcmp (declp -> b, "__dt") == 0)
4467
        {
4468
          work -> destructor += 1;
4469
          string_clear (declp);
4470
          return;
4471
        }
4472
    }
4473
 
4474
  if (declp->p - declp->b >= 3
4475
      && declp->b[0] == 'o'
4476
      && declp->b[1] == 'p'
4477
      && strchr (cplus_markers, declp->b[2]) != NULL)
4478
    {
4479
      /* see if it's an assignment expression */
4480
      if (declp->p - declp->b >= 10 /* op$assign_ */
4481
          && memcmp (declp->b + 3, "assign_", 7) == 0)
4482
        {
4483
          for (i = 0; i < ARRAY_SIZE (optable); i++)
4484
            {
4485
              int len = declp->p - declp->b - 10;
4486
              if ((int) strlen (optable[i].in) == len
4487
                  && memcmp (optable[i].in, declp->b + 10, len) == 0)
4488
                {
4489
                  string_clear (declp);
4490
                  string_append (declp, "operator");
4491
                  string_append (declp, optable[i].out);
4492
                  string_append (declp, "=");
4493
                  break;
4494
                }
4495
            }
4496
        }
4497
      else
4498
        {
4499
          for (i = 0; i < ARRAY_SIZE (optable); i++)
4500
            {
4501
              int len = declp->p - declp->b - 3;
4502
              if ((int) strlen (optable[i].in) == len
4503
                  && memcmp (optable[i].in, declp->b + 3, len) == 0)
4504
                {
4505
                  string_clear (declp);
4506
                  string_append (declp, "operator");
4507
                  string_append (declp, optable[i].out);
4508
                  break;
4509
                }
4510
            }
4511
        }
4512
    }
4513
  else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4514
           && strchr (cplus_markers, declp->b[4]) != NULL)
4515
    {
4516
      /* type conversion operator */
4517
      tem = declp->b + 5;
4518
      if (do_type (work, &tem, &type))
4519
        {
4520
          string_clear (declp);
4521
          string_append (declp, "operator ");
4522
          string_appends (declp, &type);
4523
          string_delete (&type);
4524
        }
4525
    }
4526
  else if (declp->b[0] == '_' && declp->b[1] == '_'
4527
           && declp->b[2] == 'o' && declp->b[3] == 'p')
4528
    {
4529
      /* ANSI.  */
4530
      /* type conversion operator.  */
4531
      tem = declp->b + 4;
4532
      if (do_type (work, &tem, &type))
4533
        {
4534
          string_clear (declp);
4535
          string_append (declp, "operator ");
4536
          string_appends (declp, &type);
4537
          string_delete (&type);
4538
        }
4539
    }
4540
  else if (declp->b[0] == '_' && declp->b[1] == '_'
4541
           && ISLOWER((unsigned char)declp->b[2])
4542
           && ISLOWER((unsigned char)declp->b[3]))
4543
    {
4544
      if (declp->b[4] == '\0')
4545
        {
4546
          /* Operator.  */
4547
          for (i = 0; i < ARRAY_SIZE (optable); i++)
4548
            {
4549
              if (strlen (optable[i].in) == 2
4550
                  && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4551
                {
4552
                  string_clear (declp);
4553
                  string_append (declp, "operator");
4554
                  string_append (declp, optable[i].out);
4555
                  break;
4556
                }
4557
            }
4558
        }
4559
      else
4560
        {
4561
          if (declp->b[2] == 'a' && declp->b[5] == '\0')
4562
            {
4563
              /* Assignment.  */
4564
              for (i = 0; i < ARRAY_SIZE (optable); i++)
4565
                {
4566
                  if (strlen (optable[i].in) == 3
4567
                      && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4568
                    {
4569
                      string_clear (declp);
4570
                      string_append (declp, "operator");
4571
                      string_append (declp, optable[i].out);
4572
                      break;
4573
                    }
4574
                }
4575
            }
4576
        }
4577
    }
4578
}
4579
 
4580
/* a mini string-handling package */
4581
 
4582
static void
4583
string_need (string *s, int n)
4584
{
4585
  int tem;
4586
 
4587
  if (s->b == NULL)
4588
    {
4589
      if (n < 32)
4590
        {
4591
          n = 32;
4592
        }
4593
      s->p = s->b = XNEWVEC (char, n);
4594
      s->e = s->b + n;
4595
    }
4596
  else if (s->e - s->p < n)
4597
    {
4598
      tem = s->p - s->b;
4599
      n += tem;
4600
      n *= 2;
4601
      s->b = XRESIZEVEC (char, s->b, n);
4602
      s->p = s->b + tem;
4603
      s->e = s->b + n;
4604
    }
4605
}
4606
 
4607
static void
4608
string_delete (string *s)
4609
{
4610
  if (s->b != NULL)
4611
    {
4612
      free (s->b);
4613
      s->b = s->e = s->p = NULL;
4614
    }
4615
}
4616
 
4617
static void
4618
string_init (string *s)
4619
{
4620
  s->b = s->p = s->e = NULL;
4621
}
4622
 
4623
static void
4624
string_clear (string *s)
4625
{
4626
  s->p = s->b;
4627
}
4628
 
4629
#if 0
4630
 
4631
static int
4632
string_empty (string *s)
4633
{
4634
  return (s->b == s->p);
4635
}
4636
 
4637
#endif
4638
 
4639
static void
4640
string_append (string *p, const char *s)
4641
{
4642
  int n;
4643
  if (s == NULL || *s == '\0')
4644
    return;
4645
  n = strlen (s);
4646
  string_need (p, n);
4647
  memcpy (p->p, s, n);
4648
  p->p += n;
4649
}
4650
 
4651
static void
4652
string_appends (string *p, string *s)
4653
{
4654
  int n;
4655
 
4656
  if (s->b != s->p)
4657
    {
4658
      n = s->p - s->b;
4659
      string_need (p, n);
4660
      memcpy (p->p, s->b, n);
4661
      p->p += n;
4662
    }
4663
}
4664
 
4665
static void
4666
string_appendn (string *p, const char *s, int n)
4667
{
4668
  if (n != 0)
4669
    {
4670
      string_need (p, n);
4671
      memcpy (p->p, s, n);
4672
      p->p += n;
4673
    }
4674
}
4675
 
4676
static void
4677
string_prepend (string *p, const char *s)
4678
{
4679
  if (s != NULL && *s != '\0')
4680
    {
4681
      string_prependn (p, s, strlen (s));
4682
    }
4683
}
4684
 
4685
static void
4686
string_prepends (string *p, string *s)
4687
{
4688
  if (s->b != s->p)
4689
    {
4690
      string_prependn (p, s->b, s->p - s->b);
4691
    }
4692
}
4693
 
4694
static void
4695
string_prependn (string *p, const char *s, int n)
4696
{
4697
  char *q;
4698
 
4699
  if (n != 0)
4700
    {
4701
      string_need (p, n);
4702
      for (q = p->p - 1; q >= p->b; q--)
4703
        {
4704
          q[n] = q[0];
4705
        }
4706
      memcpy (p->b, s, n);
4707
      p->p += n;
4708
    }
4709
}
4710
 
4711
static void
4712
string_append_template_idx (string *s, int idx)
4713
{
4714
  char buf[INTBUF_SIZE + 1 /* 'T' */];
4715
  sprintf(buf, "T%d", idx);
4716
  string_append (s, buf);
4717
}

powered by: WebSVN 2.1.0

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