Subversion Repositories Kolibri OS

Rev

Rev 5191 | Details | Compare with Previous | Last modification | View Log | RSS feed

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