Bug Summary

File:src/gnu/lib/libiberty/src/cplus-dem.c
Warning:line 1281, column 4
Value stored to 'oldmangled' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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