cxxfilt 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5032 @@
1
+ /* Demangler for GNU C++
2
+ Copyright (C) 1989-2018 Free Software Foundation, Inc.
3
+ Written by James Clark (jjc@jclark.uucp)
4
+ Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5
+ Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
6
+
7
+ This file is part of the libiberty library.
8
+ Libiberty is free software; you can redistribute it and/or
9
+ modify it under the terms of the GNU Library General Public
10
+ License as published by the Free Software Foundation; either
11
+ version 2 of the License, or (at your option) any later version.
12
+
13
+ In addition to the permissions in the GNU Library General Public
14
+ License, the Free Software Foundation gives you unlimited permission
15
+ to link the compiled version of this file into combinations with other
16
+ programs, and to distribute those combinations without any restriction
17
+ coming from the use of this file. (The Library Public License
18
+ restrictions do apply in other respects; for example, they cover
19
+ modification of the file, and distribution when not linked into a
20
+ combined executable.)
21
+
22
+ Libiberty is distributed in the hope that it will be useful,
23
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25
+ Library General Public License for more details.
26
+
27
+ You should have received a copy of the GNU Library General Public
28
+ License along with libiberty; see the file COPYING.LIB. If
29
+ not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
30
+ Boston, MA 02110-1301, USA. */
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
+ /* This file lives in both GCC and libiberty. When making changes, please
39
+ try not to break either. */
40
+
41
+ #ifdef HAVE_CONFIG_H
42
+ #include "config.h"
43
+ #endif
44
+
45
+ #include "safe-ctype.h"
46
+
47
+ #include <sys/types.h>
48
+ #include <string.h>
49
+ #include <stdio.h>
50
+
51
+ #ifdef HAVE_STDLIB_H
52
+ #include <stdlib.h>
53
+ #else
54
+ void * malloc ();
55
+ void * realloc ();
56
+ #endif
57
+
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
+ #include <demangle.h>
66
+ #undef CURRENT_DEMANGLING_STYLE
67
+ #define CURRENT_DEMANGLING_STYLE work->options
68
+
69
+ #include "libiberty.h"
70
+
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
+ enum demangling_styles current_demangling_style = auto_demangling;
100
+
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
+ const struct demangler_engine libiberty_demanglers[] =
257
+ {
258
+ {
259
+ NO_DEMANGLING_STYLE_STRING,
260
+ no_demangling,
261
+ "Demangling disabled"
262
+ }
263
+ ,
264
+ {
265
+ AUTO_DEMANGLING_STYLE_STRING,
266
+ auto_demangling,
267
+ "Automatic selection based on executable"
268
+ }
269
+ ,
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
+ {
301
+ GNU_V3_DEMANGLING_STYLE_STRING,
302
+ gnu_v3_demangling,
303
+ "GNU (g++) V3 ABI-style demangling"
304
+ }
305
+ ,
306
+ {
307
+ JAVA_DEMANGLING_STYLE_STRING,
308
+ java_demangling,
309
+ "Java style demangling"
310
+ }
311
+ ,
312
+ {
313
+ GNAT_DEMANGLING_STYLE_STRING,
314
+ gnat_demangling,
315
+ "GNAT style demangling"
316
+ }
317
+ ,
318
+ {
319
+ DLANG_DEMANGLING_STYLE_STRING,
320
+ dlang_demangling,
321
+ "DLANG style demangling"
322
+ }
323
+ ,
324
+ {
325
+ RUST_DEMANGLING_STYLE_STRING,
326
+ rust_demangling,
327
+ "Rust style demangling"
328
+ }
329
+ ,
330
+ {
331
+ NULL, unknown_demangling, NULL
332
+ }
333
+ };
334
+
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
+ /* Add a routine to set the demangling style to be sure it is valid and
804
+ allow for any demangler initialization that maybe necessary. */
805
+
806
+ enum demangling_styles
807
+ cplus_demangle_set_style (enum demangling_styles style)
808
+ {
809
+ const struct demangler_engine *demangler = libiberty_demanglers;
810
+
811
+ for (; demangler->demangling_style != unknown_demangling; ++demangler)
812
+ if (style == demangler->demangling_style)
813
+ {
814
+ current_demangling_style = style;
815
+ return current_demangling_style;
816
+ }
817
+
818
+ return unknown_demangling;
819
+ }
820
+
821
+ /* Do string name to style translation */
822
+
823
+ enum demangling_styles
824
+ cplus_demangle_name_to_style (const char *name)
825
+ {
826
+ const struct demangler_engine *demangler = libiberty_demanglers;
827
+
828
+ for (; demangler->demangling_style != unknown_demangling; ++demangler)
829
+ if (strcmp (name, demangler->demangling_style_name) == 0)
830
+ return demangler->demangling_style;
831
+
832
+ return unknown_demangling;
833
+ }
834
+
835
+ /* char *cplus_demangle (const char *mangled, int options)
836
+
837
+ If MANGLED is a mangled function name produced by GNU C++, then
838
+ a pointer to a @code{malloc}ed string giving a C++ representation
839
+ of the name will be returned; otherwise NULL will be returned.
840
+ It is the caller's responsibility to free the string which
841
+ is returned.
842
+
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
+ Note that any leading underscores, or other such characters prepended by
860
+ the compilation system, are presumed to have already been stripped from
861
+ MANGLED. */
862
+
863
+ char *
864
+ cplus_demangle (const char *mangled, int options)
865
+ {
866
+ char *ret;
867
+ struct work_stuff work[1];
868
+
869
+ if (current_demangling_style == no_demangling)
870
+ return xstrdup (mangled);
871
+
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;
876
+
877
+ /* The V3 ABI demangling is implemented elsewhere. */
878
+ if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING)
879
+ {
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
+
897
+ if (ret || RUST_DEMANGLING)
898
+ return ret;
899
+ }
900
+
901
+ if (JAVA_DEMANGLING)
902
+ {
903
+ ret = java_demangle_v3 (mangled);
904
+ if (ret)
905
+ return ret;
906
+ }
907
+
908
+ if (GNAT_DEMANGLING)
909
+ return ada_demangle (mangled, options);
910
+
911
+ if (DLANG_DEMANGLING)
912
+ {
913
+ ret = dlang_demangle (mangled, options);
914
+ if (ret)
915
+ return ret;
916
+ }
917
+
918
+ ret = internal_cplus_demangle (work, mangled);
919
+ squangle_mop_up (work);
920
+ return (ret);
921
+ }
922
+
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
+ /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
945
+
946
+ char *
947
+ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
948
+ {
949
+ int len0;
950
+ const char* p;
951
+ char *d;
952
+ char *demangled = NULL;
953
+
954
+ /* Discard leading _ada_, which is used for library level subprograms. */
955
+ if (strncmp (mangled, "_ada_", 5) == 0)
956
+ mangled += 5;
957
+
958
+ /* All ada unit names are lower-case. */
959
+ if (!ISLOWER (mangled[0]))
960
+ goto unknown;
961
+
962
+ /* Most of the demangling will trivially remove chars. Operator names
963
+ may add one char but because they are always preceeded by '__' which is
964
+ replaced by '.', they eventually never expand the size.
965
+ A few special names such as '___elabs' add a few chars (at most 7), but
966
+ they occur only once. */
967
+ len0 = strlen (mangled) + 7 + 1;
968
+ demangled = XNEWVEC (char, len0);
969
+
970
+ d = demangled;
971
+ p = mangled;
972
+ while (1)
973
+ {
974
+ /* An entity names is expected. */
975
+ if (ISLOWER (*p))
976
+ {
977
+ /* An identifier, which is always lower case. */
978
+ do
979
+ *d++ = *p++;
980
+ while (ISLOWER(*p) || ISDIGIT (*p)
981
+ || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
982
+ }
983
+ else if (p[0] == 'O')
984
+ {
985
+ /* An operator name. */
986
+ static const char * const operators[][2] =
987
+ {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
988
+ {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
989
+ {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
990
+ {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
991
+ {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
992
+ {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
993
+ {"Oexpon", "**"}, {NULL, NULL}};
994
+ int k;
995
+
996
+ for (k = 0; operators[k][0] != NULL; k++)
997
+ {
998
+ size_t slen = strlen (operators[k][0]);
999
+ if (strncmp (p, operators[k][0], slen) == 0)
1000
+ {
1001
+ p += slen;
1002
+ slen = strlen (operators[k][1]);
1003
+ *d++ = '"';
1004
+ memcpy (d, operators[k][1], slen);
1005
+ d += slen;
1006
+ *d++ = '"';
1007
+ break;
1008
+ }
1009
+ }
1010
+ /* Operator not found. */
1011
+ if (operators[k][0] == NULL)
1012
+ goto unknown;
1013
+ }
1014
+ else
1015
+ {
1016
+ /* Not a GNAT encoding. */
1017
+ goto unknown;
1018
+ }
1019
+
1020
+ /* The name can be directly followed by some uppercase letters. */
1021
+ if (p[0] == 'T' && p[1] == 'K')
1022
+ {
1023
+ /* Task stuff. */
1024
+ if (p[2] == 'B' && p[3] == 0)
1025
+ {
1026
+ /* Subprogram for task body. */
1027
+ break;
1028
+ }
1029
+ else if (p[2] == '_' && p[3] == '_')
1030
+ {
1031
+ /* Inner declarations in a task. */
1032
+ p += 4;
1033
+ *d++ = '.';
1034
+ continue;
1035
+ }
1036
+ else
1037
+ goto unknown;
1038
+ }
1039
+ if (p[0] == 'E' && p[1] == 0)
1040
+ {
1041
+ /* Exception name. */
1042
+ goto unknown;
1043
+ }
1044
+ if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
1045
+ {
1046
+ /* Protected type subprogram. */
1047
+ break;
1048
+ }
1049
+ if ((*p == 'N' || *p == 'S') && p[1] == 0)
1050
+ {
1051
+ /* Enumerated type name table. */
1052
+ goto unknown;
1053
+ }
1054
+ if (p[0] == 'X')
1055
+ {
1056
+ /* Body nested. */
1057
+ p++;
1058
+ while (p[0] == 'n' || p[0] == 'b')
1059
+ p++;
1060
+ }
1061
+ if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
1062
+ {
1063
+ /* Stream operations. */
1064
+ const char *name;
1065
+ switch (p[1])
1066
+ {
1067
+ case 'R':
1068
+ name = "'Read";
1069
+ break;
1070
+ case 'W':
1071
+ name = "'Write";
1072
+ break;
1073
+ case 'I':
1074
+ name = "'Input";
1075
+ break;
1076
+ case 'O':
1077
+ name = "'Output";
1078
+ break;
1079
+ default:
1080
+ goto unknown;
1081
+ }
1082
+ p += 2;
1083
+ strcpy (d, name);
1084
+ d += strlen (name);
1085
+ }
1086
+ else if (p[0] == 'D')
1087
+ {
1088
+ /* Controlled type operation. */
1089
+ const char *name;
1090
+ switch (p[1])
1091
+ {
1092
+ case 'F':
1093
+ name = ".Finalize";
1094
+ break;
1095
+ case 'A':
1096
+ name = ".Adjust";
1097
+ break;
1098
+ default:
1099
+ goto unknown;
1100
+ }
1101
+ strcpy (d, name);
1102
+ d += strlen (name);
1103
+ break;
1104
+ }
1105
+
1106
+ if (p[0] == '_')
1107
+ {
1108
+ /* Separator. */
1109
+ if (p[1] == '_')
1110
+ {
1111
+ /* Standard separator. Handled first. */
1112
+ p += 2;
1113
+
1114
+ if (ISDIGIT (*p))
1115
+ {
1116
+ /* Overloading number. */
1117
+ do
1118
+ p++;
1119
+ while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
1120
+ if (*p == 'X')
1121
+ {
1122
+ p++;
1123
+ while (p[0] == 'n' || p[0] == 'b')
1124
+ p++;
1125
+ }
1126
+ }
1127
+ else if (p[0] == '_' && p[1] != '_')
1128
+ {
1129
+ /* Special names. */
1130
+ static const char * const special[][2] = {
1131
+ { "_elabb", "'Elab_Body" },
1132
+ { "_elabs", "'Elab_Spec" },
1133
+ { "_size", "'Size" },
1134
+ { "_alignment", "'Alignment" },
1135
+ { "_assign", ".\":=\"" },
1136
+ { NULL, NULL }
1137
+ };
1138
+ int k;
1139
+
1140
+ for (k = 0; special[k][0] != NULL; k++)
1141
+ {
1142
+ size_t slen = strlen (special[k][0]);
1143
+ if (strncmp (p, special[k][0], slen) == 0)
1144
+ {
1145
+ p += slen;
1146
+ slen = strlen (special[k][1]);
1147
+ memcpy (d, special[k][1], slen);
1148
+ d += slen;
1149
+ break;
1150
+ }
1151
+ }
1152
+ if (special[k][0] != NULL)
1153
+ break;
1154
+ else
1155
+ goto unknown;
1156
+ }
1157
+ else
1158
+ {
1159
+ *d++ = '.';
1160
+ continue;
1161
+ }
1162
+ }
1163
+ else if (p[1] == 'B' || p[1] == 'E')
1164
+ {
1165
+ /* Entry Body or barrier Evaluation. */
1166
+ p += 2;
1167
+ while (ISDIGIT (*p))
1168
+ p++;
1169
+ if (p[0] == 's' && p[1] == 0)
1170
+ break;
1171
+ else
1172
+ goto unknown;
1173
+ }
1174
+ else
1175
+ goto unknown;
1176
+ }
1177
+
1178
+ if (p[0] == '.' && ISDIGIT (p[1]))
1179
+ {
1180
+ /* Nested subprogram. */
1181
+ p += 2;
1182
+ while (ISDIGIT (*p))
1183
+ p++;
1184
+ }
1185
+ if (*p == 0)
1186
+ {
1187
+ /* End of mangled name. */
1188
+ break;
1189
+ }
1190
+ else
1191
+ goto unknown;
1192
+ }
1193
+ *d = 0;
1194
+ return demangled;
1195
+
1196
+ unknown:
1197
+ XDELETEVEC (demangled);
1198
+ len0 = strlen (mangled);
1199
+ demangled = XNEWVEC (char, len0 + 3);
1200
+
1201
+ if (mangled[0] == '<')
1202
+ strcpy (demangled, mangled);
1203
+ else
1204
+ sprintf (demangled, "<%s>", mangled);
1205
+
1206
+ return demangled;
1207
+ }
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
+ }