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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [libiberty/] [cplus-dem.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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