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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [libiberty/] [cplus-dem.c] - Blame information for rev 1771

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

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

powered by: WebSVN 2.1.0

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