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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [libiberty/] [cplus-dem.c] - Blame information for rev 225

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

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

powered by: WebSVN 2.1.0

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