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