cxxfilt 0.1.4 → 0.1.5

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