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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [libiberty/] [cplus-dem.c] - Blame information for rev 1771

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

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

powered by: WebSVN 2.1.0

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