]> gcc.gnu.org Git - gcc.git/blame - gcc/cplus-dem.c
cse.c (rtx_cost): Add default case in enumeration switch.
[gcc.git] / gcc / cplus-dem.c
CommitLineData
a3184468 1/* Demangler for GNU C++
9663100e 2 Copyright 1989, 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
a3184468
JM
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5
6This file is part of the libiberty library.
7Libiberty is free software; you can redistribute it and/or
8modify it under the terms of the GNU Library General Public
9License as published by the Free Software Foundation; either
10version 2 of the License, or (at your option) any later version.
11
12Libiberty is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15Library General Public License for more details.
16
17You should have received a copy of the GNU Library General Public
18License along with libiberty; see the file COPYING.LIB. If
940d9d63
RK
19not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
a3184468
JM
21
22/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
23
24 This file imports xmalloc and xrealloc, which are like malloc and
25 realloc except that they generate a fatal error if there is no
0f41302f 26 available memory. */
a3184468 27
5d644692
MS
28/* This file lives in both GCC and libiberty. When making changes, please
29 try not to break either. */
30
a3184468
JM
31#include <ctype.h>
32#include <string.h>
33#include <stdio.h>
34
35#include <demangle.h>
36#undef CURRENT_DEMANGLING_STYLE
37#define CURRENT_DEMANGLING_STYLE work->options
38
39extern char *xmalloc PARAMS((unsigned));
40extern char *xrealloc PARAMS((char *, unsigned));
a3184468 41
9663100e
ILT
42static const char *mystrstr PARAMS ((const char *, const char *));
43
44static const char *
f83d4617 45mystrstr (s1, s2)
9663100e 46 const char *s1, *s2;
c4b5dcfb 47{
9663100e 48 register const char *p = s1;
c4b5dcfb
RK
49 register int len = strlen (s2);
50
51 for (; (p = strchr (p, *s2)) != 0; p++)
52 {
53 if (strncmp (p, s2, len) == 0)
54 {
55 return (p);
56 }
57 }
58 return (0);
59}
c4b5dcfb 60
a3184468
JM
61/* In order to allow a single demangler executable to demangle strings
62 using various common values of CPLUS_MARKER, as well as any specific
63 one set at compile time, we maintain a string containing all the
64 commonly used ones, and check to see if the marker we are looking for
65 is in that string. CPLUS_MARKER is usually '$' on systems where the
66 assembler can deal with that. Where the assembler can't, it's usually
67 '.' (but on many systems '.' is used for other things). We put the
68 current defined CPLUS_MARKER first (which defaults to '$'), followed
69 by the next most common value, followed by an explicit '$' in case
70 the value of CPLUS_MARKER is not '$'.
71
72 We could avoid this if we could just get g++ to tell us what the actual
73 cplus marker character is as part of the debug information, perhaps by
74 ensuring that it is the character that terminates the gcc<n>_compiled
0f41302f 75 marker symbol (FIXME). */
a3184468
JM
76
77#if !defined (CPLUS_MARKER)
78#define CPLUS_MARKER '$'
79#endif
80
81enum demangling_styles current_demangling_style = gnu_demangling;
82
83static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
84
85void
86set_cplus_marker_for_demangling (ch)
87 int ch;
88{
5d644692 89 cplus_markers[0] = ch;
a3184468
JM
90}
91
92/* Stuff that is shared between sub-routines.
0f41302f 93 Using a shared structure allows cplus_demangle to be reentrant. */
a3184468
JM
94
95struct work_stuff
96{
97 int options;
98 char **typevec;
99 int ntypes;
100 int typevec_size;
101 int constructor;
102 int destructor;
103 int static_type; /* A static member function */
104 int const_type; /* A const member function */
37f6b6bf
MM
105 char **tmpl_argvec; /* Template function arguments. */
106 int ntmpl_args; /* The number of template function arguments. */
a3184468
JM
107};
108
109#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
110#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
111
112static const struct optable
113{
114 const char *in;
115 const char *out;
116 int flags;
117} optable[] = {
118 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
119 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
120 {"new", " new", 0}, /* old (1.91, and 1.x) */
121 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
122 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
123 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
124 {"as", "=", DMGL_ANSI}, /* ansi */
125 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
126 {"eq", "==", DMGL_ANSI}, /* old, ansi */
127 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
128 {"gt", ">", DMGL_ANSI}, /* old, ansi */
129 {"le", "<=", DMGL_ANSI}, /* old, ansi */
130 {"lt", "<", DMGL_ANSI}, /* old, ansi */
131 {"plus", "+", 0}, /* old */
132 {"pl", "+", DMGL_ANSI}, /* ansi */
133 {"apl", "+=", DMGL_ANSI}, /* ansi */
134 {"minus", "-", 0}, /* old */
135 {"mi", "-", DMGL_ANSI}, /* ansi */
136 {"ami", "-=", DMGL_ANSI}, /* ansi */
137 {"mult", "*", 0}, /* old */
138 {"ml", "*", DMGL_ANSI}, /* ansi */
139 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
140 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
141 {"convert", "+", 0}, /* old (unary +) */
142 {"negate", "-", 0}, /* old (unary -) */
143 {"trunc_mod", "%", 0}, /* old */
144 {"md", "%", DMGL_ANSI}, /* ansi */
145 {"amd", "%=", DMGL_ANSI}, /* ansi */
146 {"trunc_div", "/", 0}, /* old */
147 {"dv", "/", DMGL_ANSI}, /* ansi */
148 {"adv", "/=", DMGL_ANSI}, /* ansi */
149 {"truth_andif", "&&", 0}, /* old */
150 {"aa", "&&", DMGL_ANSI}, /* ansi */
151 {"truth_orif", "||", 0}, /* old */
152 {"oo", "||", DMGL_ANSI}, /* ansi */
153 {"truth_not", "!", 0}, /* old */
154 {"nt", "!", DMGL_ANSI}, /* ansi */
155 {"postincrement","++", 0}, /* old */
156 {"pp", "++", DMGL_ANSI}, /* ansi */
157 {"postdecrement","--", 0}, /* old */
158 {"mm", "--", DMGL_ANSI}, /* ansi */
159 {"bit_ior", "|", 0}, /* old */
160 {"or", "|", DMGL_ANSI}, /* ansi */
161 {"aor", "|=", DMGL_ANSI}, /* ansi */
162 {"bit_xor", "^", 0}, /* old */
163 {"er", "^", DMGL_ANSI}, /* ansi */
164 {"aer", "^=", DMGL_ANSI}, /* ansi */
165 {"bit_and", "&", 0}, /* old */
166 {"ad", "&", DMGL_ANSI}, /* ansi */
167 {"aad", "&=", DMGL_ANSI}, /* ansi */
168 {"bit_not", "~", 0}, /* old */
169 {"co", "~", DMGL_ANSI}, /* ansi */
170 {"call", "()", 0}, /* old */
171 {"cl", "()", DMGL_ANSI}, /* ansi */
172 {"alshift", "<<", 0}, /* old */
173 {"ls", "<<", DMGL_ANSI}, /* ansi */
174 {"als", "<<=", DMGL_ANSI}, /* ansi */
175 {"arshift", ">>", 0}, /* old */
176 {"rs", ">>", DMGL_ANSI}, /* ansi */
177 {"ars", ">>=", DMGL_ANSI}, /* ansi */
178 {"component", "->", 0}, /* old */
179 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
180 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
181 {"indirect", "*", 0}, /* old */
182 {"method_call", "->()", 0}, /* old */
183 {"addr", "&", 0}, /* old (unary &) */
184 {"array", "[]", 0}, /* old */
185 {"vc", "[]", DMGL_ANSI}, /* ansi */
186 {"compound", ", ", 0}, /* old */
187 {"cm", ", ", DMGL_ANSI}, /* ansi */
188 {"cond", "?:", 0}, /* old */
ddd5a7c1 189 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
a3184468 190 {"max", ">?", 0}, /* old */
ddd5a7c1 191 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
a3184468 192 {"min", "<?", 0}, /* old */
ddd5a7c1 193 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
a3184468
JM
194 {"nop", "", 0}, /* old (for operator=) */
195 {"rm", "->*", DMGL_ANSI} /* ansi */
196};
197
198
199typedef struct string /* Beware: these aren't required to be */
0f41302f 200{ /* '\0' terminated. */
a3184468
JM
201 char *b; /* pointer to start of string */
202 char *p; /* pointer after last character */
203 char *e; /* pointer after end of allocated space */
204} string;
205
206#define STRING_EMPTY(str) ((str) -> b == (str) -> p)
207#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
5d644692 208 string_prepend(str, " ");}
a3184468 209#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
5d644692 210 string_append(str, " ");}
a3184468
JM
211
212#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
213#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
214
215/* Prototypes for local functions */
216
217static char *
218mop_up PARAMS ((struct work_stuff *, string *, int));
219
220#if 0
221static int
222demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
223#endif
224
225static int
226demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
37f6b6bf 227 string *, int));
a3184468 228
9663100e
ILT
229static int
230arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
231 const char **));
232
233static void
234demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
235
236static int
237demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
238
a3184468
JM
239static int
240demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
241 int, int));
242
243static int
244demangle_class PARAMS ((struct work_stuff *, const char **, string *));
245
246static int
247demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
248
249static int
250demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
251
252static int
253demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
254
255static int
256gnu_special PARAMS ((struct work_stuff *, const char **, string *));
257
258static int
259arm_special PARAMS ((struct work_stuff *, const char **, string *));
260
261static void
262string_need PARAMS ((string *, int));
263
264static void
265string_delete PARAMS ((string *));
266
267static void
268string_init PARAMS ((string *));
269
270static void
271string_clear PARAMS ((string *));
272
273#if 0
274static int
275string_empty PARAMS ((string *));
276#endif
277
278static void
279string_append PARAMS ((string *, const char *));
280
281static void
282string_appends PARAMS ((string *, string *));
283
284static void
285string_appendn PARAMS ((string *, const char *, int));
286
287static void
288string_prepend PARAMS ((string *, const char *));
289
290static void
291string_prependn PARAMS ((string *, const char *, int));
292
293static int
294get_count PARAMS ((const char **, int *));
295
296static int
297consume_count PARAMS ((const char **));
298
37f6b6bf
MM
299static int
300consume_count_with_underscores PARAMS ((const char**));
301
a3184468
JM
302static int
303demangle_args PARAMS ((struct work_stuff *, const char **, string *));
304
305static int
306do_type PARAMS ((struct work_stuff *, const char **, string *));
307
308static int
309do_arg PARAMS ((struct work_stuff *, const char **, string *));
310
311static void
312demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
313 const char *));
314
315static void
316remember_type PARAMS ((struct work_stuff *, const char *, int));
317
318static void
319forget_types PARAMS ((struct work_stuff *));
320
321static void
322string_prepends PARAMS ((string *, string *));
323
324/* Translate count to integer, consuming tokens in the process.
325 Conversion terminates on the first non-digit character.
326 Trying to consume something that isn't a count results in
0f41302f 327 no consumption of input and a return of 0. */
a3184468
JM
328
329static int
330consume_count (type)
5d644692 331 const char **type;
a3184468 332{
5d644692 333 int count = 0;
a3184468 334
5d644692
MS
335 while (isdigit (**type))
336 {
337 count *= 10;
338 count += **type - '0';
339 (*type)++;
340 }
341 return (count);
a3184468
JM
342}
343
37f6b6bf 344
956d6950 345/* Like consume_count, but for counts that are preceded and followed
37f6b6bf
MM
346 by '_' if they are greater than 10. Also, -1 is returned for
347 failure, since 0 can be a valid value. */
348
349static int
350consume_count_with_underscores (mangled)
351 const char **mangled;
352{
353 int idx;
354
355 if (**mangled == '_')
356 {
357 (*mangled)++;
358 if (!isdigit (**mangled))
359 return -1;
360
361 idx = consume_count (mangled);
362 if (**mangled != '_')
363 /* The trailing underscore was missing. */
364 return -1;
365
366 (*mangled)++;
367 }
368 else
369 {
370 if (**mangled < '0' || **mangled > '9')
371 return -1;
372
373 idx = **mangled - '0';
374 (*mangled)++;
375 }
376
377 return idx;
378}
379
a3184468
JM
380int
381cplus_demangle_opname (opname, result, options)
47fd14f4 382 const char *opname;
a3184468
JM
383 char *result;
384 int options;
385{
386 int len, i, len1, ret;
387 string type;
388 struct work_stuff work[1];
389 const char *tem;
390
391 len = strlen(opname);
392 result[0] = '\0';
393 ret = 0;
394 work->options = options;
395
396 if (opname[0] == '_' && opname[1] == '_'
5d644692 397 && opname[2] == 'o' && opname[3] == 'p')
a3184468
JM
398 {
399 /* ANSI. */
400 /* type conversion operator. */
401 tem = opname + 4;
402 if (do_type (work, &tem, &type))
403 {
404 strcat (result, "operator ");
405 strncat (result, type.b, type.p - type.b);
406 string_delete (&type);
407 ret = 1;
408 }
409 }
410 else if (opname[0] == '_' && opname[1] == '_'
411 && opname[2] >= 'a' && opname[2] <= 'z'
412 && opname[3] >= 'a' && opname[3] <= 'z')
413 {
414 if (opname[4] == '\0')
415 {
416 /* Operator. */
417 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
418 {
419 if (strlen (optable[i].in) == 2
420 && memcmp (optable[i].in, opname + 2, 2) == 0)
421 {
422 strcat (result, "operator");
423 strcat (result, optable[i].out);
424 ret = 1;
425 break;
426 }
427 }
428 }
429 else
430 {
431 if (opname[2] == 'a' && opname[5] == '\0')
432 {
0f41302f 433 /* Assignment. */
a3184468
JM
434 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
435 {
436 if (strlen (optable[i].in) == 3
437 && memcmp (optable[i].in, opname + 2, 3) == 0)
438 {
439 strcat (result, "operator");
440 strcat (result, optable[i].out);
441 ret = 1;
442 break;
443 }
444 }
445 }
446 }
447 }
448 else if (len >= 3
5d644692
MS
449 && opname[0] == 'o'
450 && opname[1] == 'p'
451 && strchr (cplus_markers, opname[2]) != NULL)
a3184468
JM
452 {
453 /* see if it's an assignment expression */
454 if (len >= 10 /* op$assign_ */
455 && memcmp (opname + 3, "assign_", 7) == 0)
456 {
457 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
458 {
459 len1 = len - 10;
460 if (strlen (optable[i].in) == len1
461 && memcmp (optable[i].in, opname + 10, len1) == 0)
462 {
463 strcat (result, "operator");
464 strcat (result, optable[i].out);
465 strcat (result, "=");
466 ret = 1;
467 break;
468 }
469 }
470 }
471 else
472 {
473 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
474 {
475 len1 = len - 3;
476 if (strlen (optable[i].in) == len1
477 && memcmp (optable[i].in, opname + 3, len1) == 0)
478 {
479 strcat (result, "operator");
480 strcat (result, optable[i].out);
481 ret = 1;
482 break;
483 }
484 }
485 }
486 }
487 else if (len >= 5 && memcmp (opname, "type", 4) == 0
488 && strchr (cplus_markers, opname[4]) != NULL)
489 {
490 /* type conversion operator */
491 tem = opname + 5;
492 if (do_type (work, &tem, &type))
493 {
494 strcat (result, "operator ");
495 strncat (result, type.b, type.p - type.b);
496 string_delete (&type);
497 ret = 1;
498 }
499 }
500 return ret;
501
502}
503/* Takes operator name as e.g. "++" and returns mangled
504 operator name (e.g. "postincrement_expr"), or NULL if not found.
505
506 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
507 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
508
47fd14f4 509const char *
a3184468 510cplus_mangle_opname (opname, options)
47fd14f4 511 const char *opname;
a3184468
JM
512 int options;
513{
514 int i;
515 int len;
516
517 len = strlen (opname);
518 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
519 {
520 if (strlen (optable[i].out) == len
521 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
522 && memcmp (optable[i].out, opname, len) == 0)
47fd14f4 523 return optable[i].in;
a3184468
JM
524 }
525 return (0);
526}
527
a3184468
JM
528/* char *cplus_demangle (const char *mangled, int options)
529
530 If MANGLED is a mangled function name produced by GNU C++, then
531 a pointer to a malloced string giving a C++ representation
532 of the name will be returned; otherwise NULL will be returned.
533 It is the caller's responsibility to free the string which
534 is returned.
535
536 The OPTIONS arg may contain one or more of the following bits:
537
538 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
539 included.
540 DMGL_PARAMS Function parameters are included.
541
542 For example,
543
544 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
545 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
546 cplus_demangle ("foo__1Ai", 0) => "A::foo"
547
548 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
549 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
550 cplus_demangle ("foo__1Afe", 0) => "A::foo"
551
552 Note that any leading underscores, or other such characters prepended by
553 the compilation system, are presumed to have already been stripped from
554 MANGLED. */
555
556char *
557cplus_demangle (mangled, options)
558 const char *mangled;
559 int options;
560{
561 string decl;
562 int success = 0;
563 struct work_stuff work[1];
564 char *demangled = NULL;
565
566 if ((mangled != NULL) && (*mangled != '\0'))
567 {
568 memset ((char *) work, 0, sizeof (work));
569 work -> options = options;
570 if ((work->options & DMGL_STYLE_MASK) == 0)
571 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
572
573 string_init (&decl);
574
575 /* First check to see if gnu style demangling is active and if the
576 string to be demangled contains a CPLUS_MARKER. If so, attempt to
577 recognize one of the gnu special forms rather than looking for a
578 standard prefix. In particular, don't worry about whether there
579 is a "__" string in the mangled string. Consider "_$_5__foo" for
0f41302f 580 example. */
a3184468
JM
581
582 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
583 {
584 success = gnu_special (work, &mangled, &decl);
585 }
586 if (!success)
587 {
588 success = demangle_prefix (work, &mangled, &decl);
589 }
590 if (success && (*mangled != '\0'))
591 {
592 success = demangle_signature (work, &mangled, &decl);
593 }
594 if (work->constructor == 2)
595 {
596 string_prepend(&decl, "global constructors keyed to ");
597 work->constructor = 0;
598 }
599 else if (work->destructor == 2)
600 {
601 string_prepend(&decl, "global destructors keyed to ");
602 work->destructor = 0;
603 }
604 demangled = mop_up (work, &decl, success);
605 }
606 return (demangled);
607}
608
609static char *
610mop_up (work, declp, success)
611 struct work_stuff *work;
612 string *declp;
613 int success;
614{
615 char *demangled = NULL;
616
0f41302f 617 /* Discard the remembered types, if any. */
a3184468
JM
618
619 forget_types (work);
620 if (work -> typevec != NULL)
621 {
622 free ((char *) work -> typevec);
623 }
37f6b6bf
MM
624 if (work->tmpl_argvec)
625 {
626 int i;
627
628 for (i = 0; i < work->ntmpl_args; i++)
629 if (work->tmpl_argvec[i])
630 free ((char*) work->tmpl_argvec[i]);
631
632 free ((char*) work->tmpl_argvec);
633 }
634
a3184468 635 /* If demangling was successful, ensure that the demangled string is null
0f41302f 636 terminated and return it. Otherwise, free the demangling decl. */
a3184468
JM
637
638 if (!success)
639 {
640 string_delete (declp);
641 }
642 else
643 {
644 string_appendn (declp, "", 1);
645 demangled = declp -> b;
646 }
647 return (demangled);
648}
649
650/*
651
652LOCAL FUNCTION
653
654 demangle_signature -- demangle the signature part of a mangled name
655
656SYNOPSIS
657
658 static int
659 demangle_signature (struct work_stuff *work, const char **mangled,
660 string *declp);
661
662DESCRIPTION
663
664 Consume and demangle the signature portion of the mangled name.
665
666 DECLP is the string where demangled output is being built. At
667 entry it contains the demangled root name from the mangled name
668 prefix. I.E. either a demangled operator name or the root function
669 name. In some special cases, it may contain nothing.
670
671 *MANGLED points to the current unconsumed location in the mangled
672 name. As tokens are consumed and demangling is performed, the
673 pointer is updated to continuously point at the next token to
674 be consumed.
675
676 Demangling GNU style mangled names is nasty because there is no
677 explicit token that marks the start of the outermost function
0f41302f 678 argument list. */
a3184468
JM
679
680static int
681demangle_signature (work, mangled, declp)
682 struct work_stuff *work;
683 const char **mangled;
684 string *declp;
685{
686 int success = 1;
687 int func_done = 0;
688 int expect_func = 0;
37f6b6bf 689 int expect_return_type = 0;
a3184468
JM
690 const char *oldmangled = NULL;
691 string trawname;
692 string tname;
693
694 while (success && (**mangled != '\0'))
695 {
696 switch (**mangled)
697 {
5d644692
MS
698 case 'Q':
699 oldmangled = *mangled;
700 success = demangle_qualified (work, mangled, declp, 1, 0);
701 if (success)
702 {
703 remember_type (work, oldmangled, *mangled - oldmangled);
704 }
705 if (AUTO_DEMANGLING || GNU_DEMANGLING)
706 {
707 expect_func = 1;
708 }
709 oldmangled = NULL;
710 break;
a3184468 711
5d644692
MS
712 case 'S':
713 /* Static member function */
714 if (oldmangled == NULL)
715 {
716 oldmangled = *mangled;
717 }
718 (*mangled)++;
719 work -> static_type = 1;
720 break;
a3184468 721
5d644692
MS
722 case 'C':
723 /* a const member function */
724 if (oldmangled == NULL)
725 {
726 oldmangled = *mangled;
727 }
728 (*mangled)++;
729 work -> const_type = 1;
730 break;
a3184468 731
5d644692
MS
732 case '0': case '1': case '2': case '3': case '4':
733 case '5': case '6': case '7': case '8': case '9':
734 if (oldmangled == NULL)
735 {
736 oldmangled = *mangled;
737 }
738 success = demangle_class (work, mangled, declp);
739 if (success)
740 {
741 remember_type (work, oldmangled, *mangled - oldmangled);
742 }
743 if (AUTO_DEMANGLING || GNU_DEMANGLING)
744 {
745 expect_func = 1;
746 }
747 oldmangled = NULL;
748 break;
a3184468 749
5d644692
MS
750 case 'F':
751 /* Function */
752 /* ARM style demangling includes a specific 'F' character after
a3184468
JM
753 the class name. For GNU style, it is just implied. So we can
754 safely just consume any 'F' at this point and be compatible
0f41302f 755 with either style. */
a3184468 756
5d644692
MS
757 oldmangled = NULL;
758 func_done = 1;
759 (*mangled)++;
a3184468 760
5d644692
MS
761 /* For lucid/ARM style we have to forget any types we might
762 have remembered up to this point, since they were not argument
763 types. GNU style considers all types seen as available for
764 back references. See comment in demangle_args() */
a3184468 765
5d644692
MS
766 if (LUCID_DEMANGLING || ARM_DEMANGLING)
767 {
768 forget_types (work);
769 }
770 success = demangle_args (work, mangled, declp);
771 break;
a3184468 772
5d644692
MS
773 case 't':
774 /* G++ Template */
775 string_init(&trawname);
776 string_init(&tname);
777 if (oldmangled == NULL)
778 {
779 oldmangled = *mangled;
780 }
37f6b6bf 781 success = demangle_template (work, mangled, &tname, &trawname, 1);
5d644692
MS
782 if (success)
783 {
784 remember_type (work, oldmangled, *mangled - oldmangled);
785 }
a29f4129 786 string_append(&tname, (work -> options & DMGL_JAVA) ? "." : "::");
5d644692
MS
787 string_prepends(declp, &tname);
788 if (work -> destructor & 1)
789 {
790 string_prepend (&trawname, "~");
791 string_appends (declp, &trawname);
792 work->destructor -= 1;
793 }
794 if ((work->constructor & 1) || (work->destructor & 1))
795 {
796 string_appends (declp, &trawname);
797 work->constructor -= 1;
798 }
799 string_delete(&trawname);
800 string_delete(&tname);
801 oldmangled = NULL;
802 expect_func = 1;
803 break;
a3184468 804
5d644692 805 case '_':
37f6b6bf
MM
806 if (GNU_DEMANGLING && expect_return_type)
807 {
808 /* Read the return type. */
809 string return_type;
810 string_init (&return_type);
811
812 (*mangled)++;
813 success = do_type (work, mangled, &return_type);
814 APPEND_BLANK (&return_type);
815
816 string_prepends (declp, &return_type);
817 string_delete (&return_type);
818 break;
819 }
820 else
821 /* At the outermost level, we cannot have a return type specified,
822 so if we run into another '_' at this point we are dealing with
823 a mangled name that is either bogus, or has been mangled by
824 some algorithm we don't know how to deal with. So just
825 reject the entire demangling. */
826 success = 0;
5d644692 827 break;
a3184468 828
37f6b6bf
MM
829 case 'H':
830 if (GNU_DEMANGLING)
831 {
832 /* A G++ template function. Read the template arguments. */
833 success = demangle_template (work, mangled, declp, 0, 0);
041c97f2
MM
834 if (!(work->constructor & 1))
835 expect_return_type = 1;
37f6b6bf
MM
836 (*mangled)++;
837 break;
838 }
839 else
840 /* fall through */
841 ;
842
5d644692
MS
843 default:
844 if (AUTO_DEMANGLING || GNU_DEMANGLING)
a3184468 845 {
5d644692
MS
846 /* Assume we have stumbled onto the first outermost function
847 argument token, and start processing args. */
a3184468
JM
848 func_done = 1;
849 success = demangle_args (work, mangled, declp);
850 }
5d644692
MS
851 else
852 {
853 /* Non-GNU demanglers use a specific token to mark the start
854 of the outermost function argument tokens. Typically 'F',
855 for ARM-demangling, for example. So if we find something
856 we are not prepared for, it must be an error. */
857 success = 0;
858 }
859 break;
a3184468 860 }
5d644692
MS
861 /*
862 if (AUTO_DEMANGLING || GNU_DEMANGLING)
863 */
864 {
865 if (success && expect_func)
866 {
867 func_done = 1;
868 success = demangle_args (work, mangled, declp);
37f6b6bf
MM
869 /* Since template include the mangling of their return types,
870 we must set expect_func to 0 so that we don't try do
871 demangle more arguments the next time we get here. */
872 expect_func = 0;
5d644692
MS
873 }
874 }
a3184468
JM
875 }
876 if (success && !func_done)
877 {
878 if (AUTO_DEMANGLING || GNU_DEMANGLING)
879 {
880 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
881 bar__3fooi is 'foo::bar(int)'. We get here when we find the
882 first case, and need to ensure that the '(void)' gets added to
883 the current declp. Note that with ARM, the first case
884 represents the name of a static data member 'foo::bar',
0f41302f 885 which is in the current declp, so we leave it alone. */
a3184468
JM
886 success = demangle_args (work, mangled, declp);
887 }
888 }
889 if (success && work -> static_type && PRINT_ARG_TYPES)
890 {
891 string_append (declp, " static");
892 }
893 if (success && work -> const_type && PRINT_ARG_TYPES)
894 {
895 string_append (declp, " const");
896 }
897 return (success);
898}
899
900#if 0
901
902static int
903demangle_method_args (work, mangled, declp)
904 struct work_stuff *work;
905 const char **mangled;
906 string *declp;
907{
908 int success = 0;
909
910 if (work -> static_type)
911 {
912 string_append (declp, *mangled + 1);
913 *mangled += strlen (*mangled);
914 success = 1;
915 }
916 else
917 {
918 success = demangle_args (work, mangled, declp);
919 }
920 return (success);
921}
922
923#endif
924
925static int
37f6b6bf 926demangle_template (work, mangled, tname, trawname, is_type)
a3184468
JM
927 struct work_stuff *work;
928 const char **mangled;
929 string *tname;
930 string *trawname;
37f6b6bf 931 int is_type;
a3184468
JM
932{
933 int i;
934 int is_pointer;
935 int is_real;
936 int is_integral;
937 int is_char;
938 int is_bool;
939 int r;
940 int need_comma = 0;
941 int success = 0;
942 int done;
943 const char *old_p;
944 const char *start;
945 int symbol_len;
37f6b6bf 946 int is_java_array = 0;
a3184468
JM
947 string temp;
948
949 (*mangled)++;
37f6b6bf 950 if (is_type)
a3184468 951 {
37f6b6bf
MM
952 start = *mangled;
953 /* get template name */
954 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
955 {
956 return (0);
957 }
958 if (trawname)
959 string_appendn (trawname, *mangled, r);
960 is_java_array = (work -> options & DMGL_JAVA)
961 && strncmp (*mangled, "JArray1Z", 8) == 0;
962 if (! is_java_array)
963 {
964 string_appendn (tname, *mangled, r);
965 }
966 *mangled += r;
a29f4129 967 }
37f6b6bf
MM
968 if (!is_java_array)
969 string_append (tname, "<");
a3184468
JM
970 /* get size of template parameter list */
971 if (!get_count (mangled, &r))
972 {
973 return (0);
974 }
37f6b6bf
MM
975 if (!is_type)
976 {
977 /* Create an array for saving the template argument values. */
978 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
979 work->ntmpl_args = r;
980 for (i = 0; i < r; i++)
981 work->tmpl_argvec[i] = 0;
982 }
a3184468
JM
983 for (i = 0; i < r; i++)
984 {
985 if (need_comma)
986 {
987 string_append (tname, ", ");
988 }
989 /* Z for type parameters */
990 if (**mangled == 'Z')
991 {
992 (*mangled)++;
993 /* temp is initialized in do_type */
994 success = do_type (work, mangled, &temp);
995 if (success)
996 {
997 string_appends (tname, &temp);
37f6b6bf
MM
998
999 if (!is_type)
1000 {
1001 /* Save the template argument. */
1002 int len = temp.p - temp.b;
1003 work->tmpl_argvec[i] = xmalloc (len + 1);
1004 memcpy (work->tmpl_argvec[i], temp.b, len);
1005 work->tmpl_argvec[i][len] = '\0';
1006 }
a3184468
JM
1007 }
1008 string_delete(&temp);
1009 if (!success)
1010 {
1011 break;
1012 }
1013 }
1014 else
1015 {
37f6b6bf
MM
1016 string param;
1017 string* s;
1018
a3184468
JM
1019 /* otherwise, value parameter */
1020 old_p = *mangled;
1021 is_pointer = 0;
1022 is_real = 0;
1023 is_integral = 0;
1024 is_char = 0;
943a140b 1025 is_bool = 0;
a3184468
JM
1026 done = 0;
1027 /* temp is initialized in do_type */
1028 success = do_type (work, mangled, &temp);
5d644692
MS
1029 /*
1030 if (success)
a3184468 1031 {
37f6b6bf 1032 string_appends (s, &temp);
a3184468 1033 }
5d644692 1034 */
a3184468
JM
1035 string_delete(&temp);
1036 if (!success)
1037 {
1038 break;
1039 }
5d644692 1040 /*
37f6b6bf 1041 string_append (s, "=");
5d644692 1042 */
37f6b6bf
MM
1043
1044 if (!is_type)
1045 {
1046 s = &param;
1047 string_init (s);
1048 }
1049 else
1050 s = tname;
1051
a3184468
JM
1052 while (*old_p && !done)
1053 {
1054 switch (*old_p)
1055 {
5d644692
MS
1056 case 'P':
1057 case 'p':
1058 case 'R':
1059 done = is_pointer = 1;
1060 break;
1061 case 'C': /* const */
1062 case 'S': /* explicitly signed [char] */
1063 case 'U': /* unsigned */
1064 case 'V': /* volatile */
1065 case 'F': /* function */
1066 case 'M': /* member function */
1067 case 'O': /* ??? */
5ff660f0 1068 case 'J': /* complex */
5d644692
MS
1069 old_p++;
1070 continue;
1071 case 'Q': /* qualified name */
1072 done = is_integral = 1;
1073 break;
1074 case 'T': /* remembered type */
1075 abort ();
1076 break;
1077 case 'v': /* void */
1078 abort ();
1079 break;
1080 case 'x': /* long long */
1081 case 'l': /* long */
1082 case 'i': /* int */
1083 case 's': /* short */
1084 case 'w': /* wchar_t */
1085 done = is_integral = 1;
1086 break;
1087 case 'b': /* bool */
1088 done = is_bool = 1;
1089 break;
1090 case 'c': /* char */
1091 done = is_char = 1;
1092 break;
1093 case 'r': /* long double */
1094 case 'd': /* double */
1095 case 'f': /* float */
1096 done = is_real = 1;
1097 break;
1098 default:
1099 /* it's probably user defined type, let's assume
1100 it's integral, it seems hard to figure out
1101 what it really is */
1102 done = is_integral = 1;
a3184468
JM
1103 }
1104 }
37f6b6bf
MM
1105 if (**mangled == 'Y')
1106 {
1107 /* The next argument is a template parameter. */
1108 int idx;
1109
1110 (*mangled)++;
1111 idx = consume_count_with_underscores (mangled);
1112 if (idx == -1
1113 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1114 || consume_count_with_underscores (mangled) == -1)
1115 {
1116 success = 0;
1117 if (!is_type)
1118 string_delete (s);
1119 break;
1120 }
1121 if (work->tmpl_argvec)
1122 string_append (s, work->tmpl_argvec[idx]);
1123 else
1124 {
1125 char buf[10];
1126 sprintf(buf, "T%d", idx);
1127 string_append (s, buf);
1128 }
1129 }
1130 else if (is_integral)
a3184468
JM
1131 {
1132 if (**mangled == 'm')
1133 {
37f6b6bf 1134 string_appendn (s, "-", 1);
a3184468
JM
1135 (*mangled)++;
1136 }
1137 while (isdigit (**mangled))
1138 {
37f6b6bf 1139 string_appendn (s, *mangled, 1);
a3184468
JM
1140 (*mangled)++;
1141 }
1142 }
1143 else if (is_char)
1144 {
5d644692
MS
1145 char tmp[2];
1146 int val;
a3184468
JM
1147 if (**mangled == 'm')
1148 {
37f6b6bf 1149 string_appendn (s, "-", 1);
a3184468
JM
1150 (*mangled)++;
1151 }
37f6b6bf 1152 string_appendn (s, "'", 1);
a3184468
JM
1153 val = consume_count(mangled);
1154 if (val == 0)
1155 {
1156 success = 0;
37f6b6bf
MM
1157 if (!is_type)
1158 string_delete (s);
a3184468
JM
1159 break;
1160 }
1161 tmp[0] = (char)val;
1162 tmp[1] = '\0';
37f6b6bf
MM
1163 string_appendn (s, &tmp[0], 1);
1164 string_appendn (s, "'", 1);
a3184468
JM
1165 }
1166 else if (is_bool)
1167 {
1168 int val = consume_count (mangled);
1169 if (val == 0)
37f6b6bf 1170 string_appendn (s, "false", 5);
a3184468 1171 else if (val == 1)
37f6b6bf 1172 string_appendn (s, "true", 4);
a3184468
JM
1173 else
1174 success = 0;
1175 }
1176 else if (is_real)
1177 {
1178 if (**mangled == 'm')
1179 {
37f6b6bf 1180 string_appendn (s, "-", 1);
a3184468
JM
1181 (*mangled)++;
1182 }
1183 while (isdigit (**mangled))
1184 {
37f6b6bf 1185 string_appendn (s, *mangled, 1);
a3184468
JM
1186 (*mangled)++;
1187 }
1188 if (**mangled == '.') /* fraction */
1189 {
37f6b6bf 1190 string_appendn (s, ".", 1);
a3184468
JM
1191 (*mangled)++;
1192 while (isdigit (**mangled))
1193 {
37f6b6bf 1194 string_appendn (s, *mangled, 1);
a3184468
JM
1195 (*mangled)++;
1196 }
1197 }
1198 if (**mangled == 'e') /* exponent */
1199 {
37f6b6bf 1200 string_appendn (s, "e", 1);
a3184468
JM
1201 (*mangled)++;
1202 while (isdigit (**mangled))
1203 {
37f6b6bf 1204 string_appendn (s, *mangled, 1);
a3184468
JM
1205 (*mangled)++;
1206 }
1207 }
1208 }
1209 else if (is_pointer)
1210 {
c486ed79
JM
1211 symbol_len = consume_count (mangled);
1212 if (symbol_len == 0)
a3184468
JM
1213 {
1214 success = 0;
37f6b6bf
MM
1215 if (!is_type)
1216 string_delete (s);
a3184468
JM
1217 break;
1218 }
943a140b 1219 if (symbol_len == 0)
37f6b6bf 1220 string_appendn (s, "0", 1);
943a140b 1221 else
983edca4
JM
1222 {
1223 char *p = xmalloc (symbol_len + 1), *q;
1224 strncpy (p, *mangled, symbol_len);
ba9d9bfa 1225 p [symbol_len] = '\0';
983edca4 1226 q = cplus_demangle (p, work->options);
37f6b6bf 1227 string_appendn (s, "&", 1);
ba9d9bfa
JM
1228 if (q)
1229 {
37f6b6bf 1230 string_append (s, q);
ba9d9bfa
JM
1231 free (q);
1232 }
1233 else
37f6b6bf 1234 string_append (s, p);
983edca4 1235 free (p);
983edca4 1236 }
a3184468
JM
1237 *mangled += symbol_len;
1238 }
37f6b6bf
MM
1239 if (!is_type)
1240 {
1241 int len = s->p - s->b;
1242 work->tmpl_argvec[i] = xmalloc (len + 1);
1243 memcpy (work->tmpl_argvec[i], s->b, len);
1244 work->tmpl_argvec[i][len] = '\0';
1245
1246 string_appends (tname, s);
1247 string_delete (s);
1248 }
a3184468
JM
1249 }
1250 need_comma = 1;
1251 }
a29f4129
PB
1252 if (is_java_array)
1253 {
1254 string_append (tname, "[]");
1255 }
1256 else
1257 {
1258 if (tname->p[-1] == '>')
1259 string_append (tname, " ");
1260 string_append (tname, ">");
1261 }
a3184468 1262
5d644692
MS
1263 /*
1264 if (work -> static_type)
1265 {
1266 string_append (declp, *mangled + 1);
1267 *mangled += strlen (*mangled);
1268 success = 1;
a3184468 1269 }
5d644692
MS
1270 else
1271 {
1272 success = demangle_args (work, mangled, declp);
1273 }
1274 }
1275 */
a3184468
JM
1276 return (success);
1277}
1278
1279static int
1280arm_pt (work, mangled, n, anchor, args)
1281 struct work_stuff *work;
1282 const char *mangled;
1283 int n;
1284 const char **anchor, **args;
1285{
1286 /* ARM template? */
f83d4617 1287 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
a3184468 1288 {
5d644692
MS
1289 int len;
1290 *args = *anchor + 6;
1291 len = consume_count (args);
1292 if (*args + len == mangled + n && **args == '_')
1293 {
1294 ++*args;
1295 return 1;
1296 }
a3184468
JM
1297 }
1298 return 0;
1299}
1300
1301static void
1302demangle_arm_pt (work, mangled, n, declp)
1303 struct work_stuff *work;
1304 const char **mangled;
1305 int n;
1306 string *declp;
1307{
1308 const char *p;
1309 const char *args;
1310 const char *e = *mangled + n;
1311
1312 /* ARM template? */
1313 if (arm_pt (work, *mangled, n, &p, &args))
5d644692
MS
1314 {
1315 string arg;
1316 string_init (&arg);
1317 string_appendn (declp, *mangled, p - *mangled);
1318 string_append (declp, "<");
1319 /* should do error checking here */
1320 while (args < e) {
1321 string_clear (&arg);
1322 do_type (work, &args, &arg);
1323 string_appends (declp, &arg);
1324 string_append (declp, ",");
1325 }
1326 string_delete (&arg);
1327 --declp->p;
1328 string_append (declp, ">");
1329 }
a3184468 1330 else
5d644692
MS
1331 {
1332 string_appendn (declp, *mangled, n);
1333 }
a3184468
JM
1334 *mangled += n;
1335}
1336
1337static int
1338demangle_class_name (work, mangled, declp)
1339 struct work_stuff *work;
1340 const char **mangled;
1341 string *declp;
1342{
1343 int n;
1344 int success = 0;
1345
1346 n = consume_count (mangled);
1347 if (strlen (*mangled) >= n)
5d644692
MS
1348 {
1349 demangle_arm_pt (work, mangled, n, declp);
1350 success = 1;
1351 }
a3184468
JM
1352
1353 return (success);
1354}
1355
1356/*
1357
1358LOCAL FUNCTION
1359
1360 demangle_class -- demangle a mangled class sequence
1361
1362SYNOPSIS
1363
1364 static int
1365 demangle_class (struct work_stuff *work, const char **mangled,
1366 strint *declp)
1367
1368DESCRIPTION
1369
1370 DECLP points to the buffer into which demangling is being done.
1371
1372 *MANGLED points to the current token to be demangled. On input,
1373 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1374 On exit, it points to the next token after the mangled class on
1375 success, or the first unconsumed token on failure.
1376
abc95ed3 1377 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
a3184468
JM
1378 we are demangling a constructor or destructor. In this case
1379 we prepend "class::class" or "class::~class" to DECLP.
1380
1381 Otherwise, we prepend "class::" to the current DECLP.
1382
1383 Reset the constructor/destructor flags once they have been
1384 "consumed". This allows demangle_class to be called later during
1385 the same demangling, to do normal class demangling.
1386
1387 Returns 1 if demangling is successful, 0 otherwise.
1388
1389*/
1390
1391static int
1392demangle_class (work, mangled, declp)
1393 struct work_stuff *work;
1394 const char **mangled;
1395 string *declp;
1396{
1397 int success = 0;
1398 string class_name;
1399
1400 string_init (&class_name);
1401 if (demangle_class_name (work, mangled, &class_name))
1402 {
1403 if ((work->constructor & 1) || (work->destructor & 1))
1404 {
1405 string_prepends (declp, &class_name);
1406 if (work -> destructor & 1)
1407 {
1408 string_prepend (declp, "~");
1409 work -> destructor -= 1;
1410 }
1411 else
1412 {
1413 work -> constructor -= 1;
1414 }
1415 }
a29f4129 1416 string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
a3184468
JM
1417 string_prepends (declp, &class_name);
1418 success = 1;
1419 }
1420 string_delete (&class_name);
1421 return (success);
1422}
1423
1424/*
1425
1426LOCAL FUNCTION
1427
1428 demangle_prefix -- consume the mangled name prefix and find signature
1429
1430SYNOPSIS
1431
1432 static int
1433 demangle_prefix (struct work_stuff *work, const char **mangled,
1434 string *declp);
1435
1436DESCRIPTION
1437
1438 Consume and demangle the prefix of the mangled name.
1439
1440 DECLP points to the string buffer into which demangled output is
1441 placed. On entry, the buffer is empty. On exit it contains
1442 the root function name, the demangled operator name, or in some
1443 special cases either nothing or the completely demangled result.
1444
1445 MANGLED points to the current pointer into the mangled name. As each
1446 token of the mangled name is consumed, it is updated. Upon entry
1447 the current mangled name pointer points to the first character of
1448 the mangled name. Upon exit, it should point to the first character
1449 of the signature if demangling was successful, or to the first
1450 unconsumed character if demangling of the prefix was unsuccessful.
1451
1452 Returns 1 on success, 0 otherwise.
1453 */
1454
1455static int
1456demangle_prefix (work, mangled, declp)
1457 struct work_stuff *work;
1458 const char **mangled;
1459 string *declp;
1460{
1461 int success = 1;
1462 const char *scan;
1463 int i;
1464
1465 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1466 {
1467 char *marker = strchr (cplus_markers, (*mangled)[8]);
1468 if (marker != NULL && *marker == (*mangled)[10])
1469 {
1470 if ((*mangled)[9] == 'D')
1471 {
1472 /* it's a GNU global destructor to be executed at program exit */
1473 (*mangled) += 11;
1474 work->destructor = 2;
1475 if (gnu_special (work, mangled, declp))
1476 return success;
1477 }
1478 else if ((*mangled)[9] == 'I')
1479 {
1480 /* it's a GNU global constructor to be executed at program init */
1481 (*mangled) += 11;
1482 work->constructor = 2;
1483 if (gnu_special (work, mangled, declp))
1484 return success;
1485 }
1486 }
1487 }
1488 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1489 {
1490 /* it's a ARM global destructor to be executed at program exit */
1491 (*mangled) += 7;
1492 work->destructor = 2;
1493 }
1494 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1495 {
1496 /* it's a ARM global constructor to be executed at program initial */
1497 (*mangled) += 7;
1498 work->constructor = 2;
1499 }
1500
5d644692
MS
1501 /* This block of code is a reduction in strength time optimization
1502 of:
1503 scan = mystrstr (*mangled, "__"); */
a3184468
JM
1504
1505 {
1506 scan = *mangled;
1507
1508 do {
1509 scan = strchr (scan, '_');
1510 } while (scan != NULL && *++scan != '_');
1511
1512 if (scan != NULL) --scan;
1513 }
1514
1515 if (scan != NULL)
1516 {
1517 /* We found a sequence of two or more '_', ensure that we start at
0f41302f 1518 the last pair in the sequence. */
a3184468
JM
1519 i = strspn (scan, "_");
1520 if (i > 2)
1521 {
1522 scan += (i - 2);
1523 }
1524 }
1525
1526 if (scan == NULL)
1527 {
1528 success = 0;
1529 }
1530 else if (work -> static_type)
1531 {
1532 if (!isdigit (scan[0]) && (scan[0] != 't'))
1533 {
1534 success = 0;
1535 }
1536 }
e3da301d 1537 else if ((scan == *mangled)
041c97f2
MM
1538 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1539 || (scan[2] == 'H')))
a3184468
JM
1540 {
1541 /* The ARM says nothing about the mangling of local variables.
1542 But cfront mangles local variables by prepending __<nesting_level>
1543 to them. As an extension to ARM demangling we handle this case. */
1544 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1545 {
1546 *mangled = scan + 2;
1547 consume_count (mangled);
1548 string_append (declp, *mangled);
1549 *mangled += strlen (*mangled);
1550 success = 1;
1551 }
1552 else
1553 {
1554 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1555 names like __Q2_3foo3bar for nested type names. So don't accept
041c97f2
MM
1556 this style of constructor for cfront demangling. A GNU
1557 style member-template constructor starts with 'H'. */
a3184468
JM
1558 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1559 work -> constructor += 1;
1560 *mangled = scan + 2;
1561 }
1562 }
1563 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1564 {
1565 /* Mangled name starts with "__". Skip over any leading '_' characters,
1566 then find the next "__" that separates the prefix from the signature.
1567 */
1568 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1569 || (arm_special (work, mangled, declp) == 0))
1570 {
1571 while (*scan == '_')
1572 {
1573 scan++;
1574 }
f83d4617 1575 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
a3184468
JM
1576 {
1577 /* No separator (I.E. "__not_mangled"), or empty signature
1578 (I.E. "__not_mangled_either__") */
1579 success = 0;
1580 }
1581 else
1582 {
1583 demangle_function_name (work, mangled, declp, scan);
1584 }
1585 }
1586 }
1587 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1588 {
0f41302f 1589 /* Cfront-style parameterized type. Handled later as a signature. */
a3184468
JM
1590 success = 1;
1591
1592 /* ARM template? */
1593 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1594 }
1595 else if (*(scan + 2) != '\0')
1596 {
1597 /* Mangled name does not start with "__" but does have one somewhere
1598 in there with non empty stuff after it. Looks like a global
0f41302f 1599 function name. */
a3184468
JM
1600 demangle_function_name (work, mangled, declp, scan);
1601 }
1602 else
1603 {
1604 /* Doesn't look like a mangled name */
1605 success = 0;
1606 }
1607
1608 if (!success && (work->constructor == 2 || work->destructor == 2))
1609 {
1610 string_append (declp, *mangled);
1611 *mangled += strlen (*mangled);
1612 success = 1;
1613 }
1614 return (success);
1615}
1616
1617/*
1618
1619LOCAL FUNCTION
1620
1621 gnu_special -- special handling of gnu mangled strings
1622
1623SYNOPSIS
1624
1625 static int
1626 gnu_special (struct work_stuff *work, const char **mangled,
1627 string *declp);
1628
1629
1630DESCRIPTION
1631
1632 Process some special GNU style mangling forms that don't fit
1633 the normal pattern. For example:
1634
1635 _$_3foo (destructor for class foo)
1636 _vt$foo (foo virtual table)
1637 _vt$foo$bar (foo::bar virtual table)
1638 __vt_foo (foo virtual table, new style with thunks)
1639 _3foo$varname (static data member)
1640 _Q22rs2tu$vw (static data member)
1641 __t6vector1Zii (constructor with template)
1642 __thunk_4__$_7ostream (virtual function thunk)
1643 */
1644
1645static int
1646gnu_special (work, mangled, declp)
1647 struct work_stuff *work;
1648 const char **mangled;
1649 string *declp;
1650{
1651 int n;
1652 int success = 1;
1653 const char *p;
1654
1655 if ((*mangled)[0] == '_'
1656 && strchr (cplus_markers, (*mangled)[1]) != NULL
1657 && (*mangled)[2] == '_')
1658 {
1659 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1660 (*mangled) += 3;
1661 work -> destructor += 1;
1662 }
1663 else if ((*mangled)[0] == '_'
1664 && (((*mangled)[1] == '_'
1665 && (*mangled)[2] == 'v'
1666 && (*mangled)[3] == 't'
1667 && (*mangled)[4] == '_')
5d644692
MS
1668 || ((*mangled)[1] == 'v'
1669 && (*mangled)[2] == 't'
1670 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
a3184468
JM
1671 {
1672 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1673 and create the decl. Note that we consume the entire mangled
1674 input string, which means that demangle_signature has no work
0f41302f 1675 to do. */
a3184468
JM
1676 if ((*mangled)[2] == 'v')
1677 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1678 else
1679 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1680 while (**mangled != '\0')
1681 {
1682 p = strpbrk (*mangled, cplus_markers);
1683 switch (**mangled)
1684 {
1685 case 'Q':
1686 success = demangle_qualified (work, mangled, declp, 0, 1);
1687 break;
1688 case 't':
37f6b6bf 1689 success = demangle_template (work, mangled, declp, 0, 1);
a3184468
JM
1690 break;
1691 default:
1692 if (isdigit(*mangled[0]))
1693 {
1694 n = consume_count(mangled);
1695 }
1696 else
1697 {
1698 n = strcspn (*mangled, cplus_markers);
1699 }
1700 string_appendn (declp, *mangled, n);
1701 (*mangled) += n;
1702 }
1703
1704 if (success && ((p == NULL) || (p == *mangled)))
1705 {
1706 if (p != NULL)
1707 {
a29f4129
PB
1708 string_append (declp,
1709 (work -> options & DMGL_JAVA) ? "." : "::");
a3184468
JM
1710 (*mangled)++;
1711 }
1712 }
1713 else
1714 {
1715 success = 0;
1716 break;
1717 }
1718 }
1719 if (success)
1720 string_append (declp, " virtual table");
1721 }
1722 else if ((*mangled)[0] == '_'
1723 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1724 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1725 {
1726 /* static data member, "_3foo$varname" for example */
1727 (*mangled)++;
1728 switch (**mangled)
1729 {
5d644692
MS
1730 case 'Q':
1731 success = demangle_qualified (work, mangled, declp, 0, 1);
1732 break;
1733 case 't':
37f6b6bf 1734 success = demangle_template (work, mangled, declp, 0, 1);
5d644692
MS
1735 break;
1736 default:
1737 n = consume_count (mangled);
1738 string_appendn (declp, *mangled, n);
1739 (*mangled) += n;
a3184468
JM
1740 }
1741 if (success && (p == *mangled))
1742 {
1743 /* Consumed everything up to the cplus_marker, append the
0f41302f 1744 variable name. */
a3184468 1745 (*mangled)++;
a29f4129 1746 string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::");
a3184468
JM
1747 n = strlen (*mangled);
1748 string_appendn (declp, *mangled, n);
1749 (*mangled) += n;
1750 }
1751 else
1752 {
1753 success = 0;
1754 }
1755 }
1756 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1757 {
1758 int delta = ((*mangled) += 8, consume_count (mangled));
1759 char *method = cplus_demangle (++*mangled, work->options);
1760 if (method)
1761 {
1762 char buf[50];
1763 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1764 string_append (declp, buf);
1765 string_append (declp, method);
1766 free (method);
1767 n = strlen (*mangled);
1768 (*mangled) += n;
1769 }
1770 else
1771 {
1772 success = 0;
1773 }
1774 }
c486ed79
JM
1775 else if (strncmp (*mangled, "__t", 3) == 0
1776 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1777 {
1778 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1779 (*mangled) += 4;
1780 switch (**mangled)
1781 {
5d644692
MS
1782 case 'Q':
1783 success = demangle_qualified (work, mangled, declp, 0, 1);
1784 break;
1785 case 't':
37f6b6bf 1786 success = demangle_template (work, mangled, declp, 0, 1);
5d644692
MS
1787 break;
1788 default:
e9b1360b
BK
1789 success = demangle_fund_type (work, mangled, declp);
1790 break;
c486ed79
JM
1791 }
1792 if (success && **mangled != '\0')
1793 success = 0;
1794 if (success)
1795 string_append (declp, p);
1796 }
a3184468
JM
1797 else
1798 {
1799 success = 0;
1800 }
1801 return (success);
1802}
1803
1804/*
1805
1806LOCAL FUNCTION
1807
1808 arm_special -- special handling of ARM/lucid mangled strings
1809
1810SYNOPSIS
1811
1812 static int
1813 arm_special (struct work_stuff *work, const char **mangled,
1814 string *declp);
1815
1816
1817DESCRIPTION
1818
1819 Process some special ARM style mangling forms that don't fit
1820 the normal pattern. For example:
1821
1822 __vtbl__3foo (foo virtual table)
1823 __vtbl__3foo__3bar (bar::foo virtual table)
1824
1825 */
1826
1827static int
1828arm_special (work, mangled, declp)
1829 struct work_stuff *work;
1830 const char **mangled;
1831 string *declp;
1832{
1833 int n;
1834 int success = 1;
1835 const char *scan;
1836
1837 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1838 {
1839 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1840 and create the decl. Note that we consume the entire mangled
1841 input string, which means that demangle_signature has no work
0f41302f 1842 to do. */
a3184468
JM
1843 scan = *mangled + ARM_VTABLE_STRLEN;
1844 while (*scan != '\0') /* first check it can be demangled */
1845 {
1846 n = consume_count (&scan);
1847 if (n==0)
1848 {
1849 return (0); /* no good */
1850 }
1851 scan += n;
1852 if (scan[0] == '_' && scan[1] == '_')
1853 {
1854 scan += 2;
1855 }
1856 }
1857 (*mangled) += ARM_VTABLE_STRLEN;
1858 while (**mangled != '\0')
1859 {
1860 n = consume_count (mangled);
1861 string_prependn (declp, *mangled, n);
1862 (*mangled) += n;
1863 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1864 {
1865 string_prepend (declp, "::");
1866 (*mangled) += 2;
1867 }
1868 }
1869 string_append (declp, " virtual table");
1870 }
1871 else
1872 {
1873 success = 0;
1874 }
1875 return (success);
1876}
1877
1878/*
1879
1880LOCAL FUNCTION
1881
1882 demangle_qualified -- demangle 'Q' qualified name strings
1883
1884SYNOPSIS
1885
1886 static int
1887 demangle_qualified (struct work_stuff *, const char *mangled,
1888 string *result, int isfuncname, int append);
1889
1890DESCRIPTION
1891
1892 Demangle a qualified name, such as "Q25Outer5Inner" which is
1893 the mangled form of "Outer::Inner". The demangled output is
1894 prepended or appended to the result string according to the
1895 state of the append flag.
1896
1897 If isfuncname is nonzero, then the qualified name we are building
1898 is going to be used as a member function name, so if it is a
1899 constructor or destructor function, append an appropriate
1900 constructor or destructor name. I.E. for the above example,
1901 the result for use as a constructor is "Outer::Inner::Inner"
1902 and the result for use as a destructor is "Outer::Inner::~Inner".
1903
1904BUGS
1905
1906 Numeric conversion is ASCII dependent (FIXME).
1907
1908 */
1909
1910static int
1911demangle_qualified (work, mangled, result, isfuncname, append)
1912 struct work_stuff *work;
1913 const char **mangled;
1914 string *result;
1915 int isfuncname;
1916 int append;
1917{
1918 int qualifiers;
1919 int namelength;
1920 int success = 1;
1921 const char *p;
1922 char num[2];
1923 string temp;
1924
1925 string_init (&temp);
1926 switch ((*mangled)[1])
1927 {
1928 case '_':
1929 /* GNU mangled name with more than 9 classes. The count is preceded
1930 by an underscore (to distinguish it from the <= 9 case) and followed
1931 by an underscore. */
1932 p = *mangled + 2;
1933 qualifiers = atoi (p);
1934 if (!isdigit (*p) || *p == '0')
1935 success = 0;
1936
1937 /* Skip the digits. */
1938 while (isdigit (*p))
1939 ++p;
1940
1941 if (*p != '_')
1942 success = 0;
1943
1944 *mangled = p + 1;
1945 break;
1946
1947 case '1':
1948 case '2':
1949 case '3':
1950 case '4':
1951 case '5':
1952 case '6':
1953 case '7':
1954 case '8':
1955 case '9':
1956 /* The count is in a single digit. */
1957 num[0] = (*mangled)[1];
1958 num[1] = '\0';
1959 qualifiers = atoi (num);
1960
1961 /* If there is an underscore after the digit, skip it. This is
1962 said to be for ARM-qualified names, but the ARM makes no
1963 mention of such an underscore. Perhaps cfront uses one. */
1964 if ((*mangled)[2] == '_')
1965 {
1966 (*mangled)++;
1967 }
1968 (*mangled) += 2;
1969 break;
1970
1971 case '0':
1972 default:
1973 success = 0;
1974 }
1975
1976 if (!success)
1977 return success;
1978
1979 /* Pick off the names and collect them in the temp buffer in the order
0f41302f 1980 in which they are found, separated by '::'. */
a3184468
JM
1981
1982 while (qualifiers-- > 0)
1983 {
1984 if (*mangled[0] == '_')
1985 *mangled = *mangled + 1;
1986 if (*mangled[0] == 't')
1987 {
37f6b6bf
MM
1988 success = demangle_template(work, mangled, &temp, 0, 1);
1989 if (!success) break;
1990 }
1991 else if (*mangled[0] == 'X')
1992 {
1993 success = do_type (work, mangled, &temp);
a3184468
JM
1994 if (!success) break;
1995 }
1996 else
1997 {
1998 namelength = consume_count (mangled);
1999 if (strlen (*mangled) < namelength)
2000 {
5d644692
MS
2001 /* Simple sanity check failed */
2002 success = 0;
2003 break;
a3184468
JM
2004 }
2005 string_appendn (&temp, *mangled, namelength);
2006 *mangled += namelength;
2007 }
2008 if (qualifiers > 0)
2009 {
a29f4129 2010 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
a3184468
JM
2011 }
2012 }
2013
2014 /* If we are using the result as a function name, we need to append
2015 the appropriate '::' separated constructor or destructor name.
2016 We do this here because this is the most convenient place, where
0f41302f 2017 we already have a pointer to the name and the length of the name. */
a3184468
JM
2018
2019 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2020 {
a29f4129 2021 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
a3184468
JM
2022 if (work -> destructor & 1)
2023 {
2024 string_append (&temp, "~");
2025 }
2026 string_appendn (&temp, (*mangled) - namelength, namelength);
2027 }
2028
2029 /* Now either prepend the temp buffer to the result, or append it,
0f41302f 2030 depending upon the state of the append flag. */
a3184468
JM
2031
2032 if (append)
2033 {
2034 string_appends (result, &temp);
2035 }
2036 else
2037 {
2038 if (!STRING_EMPTY (result))
2039 {
a29f4129 2040 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
a3184468
JM
2041 }
2042 string_prepends (result, &temp);
2043 }
2044
2045 string_delete (&temp);
2046 return (success);
2047}
2048
2049/*
2050
2051LOCAL FUNCTION
2052
2053 get_count -- convert an ascii count to integer, consuming tokens
2054
2055SYNOPSIS
2056
2057 static int
2058 get_count (const char **type, int *count)
2059
2060DESCRIPTION
2061
2062 Return 0 if no conversion is performed, 1 if a string is converted.
2063*/
2064
2065static int
2066get_count (type, count)
2067 const char **type;
2068 int *count;
2069{
2070 const char *p;
2071 int n;
2072
2073 if (!isdigit (**type))
2074 {
2075 return (0);
2076 }
2077 else
2078 {
2079 *count = **type - '0';
2080 (*type)++;
2081 if (isdigit (**type))
2082 {
2083 p = *type;
2084 n = *count;
2085 do
2086 {
2087 n *= 10;
2088 n += *p - '0';
2089 p++;
2090 }
2091 while (isdigit (*p));
2092 if (*p == '_')
2093 {
2094 *type = p + 1;
2095 *count = n;
2096 }
2097 }
2098 }
2099 return (1);
2100}
2101
2102/* result will be initialised here; it will be freed on failure */
2103
2104static int
2105do_type (work, mangled, result)
2106 struct work_stuff *work;
2107 const char **mangled;
2108 string *result;
2109{
2110 int n;
2111 int done;
2112 int success;
2113 string decl;
2114 const char *remembered_type;
2115 int constp;
2116 int volatilep;
2117
2118 string_init (&decl);
2119 string_init (result);
2120
2121 done = 0;
2122 success = 1;
2123 while (success && !done)
2124 {
2125 int member;
2126 switch (**mangled)
2127 {
2128
5d644692 2129 /* A pointer type */
a3184468
JM
2130 case 'P':
2131 case 'p':
2132 (*mangled)++;
a29f4129
PB
2133 if (! (work -> options & DMGL_JAVA))
2134 string_prepend (&decl, "*");
a3184468
JM
2135 break;
2136
5d644692 2137 /* A reference type */
a3184468
JM
2138 case 'R':
2139 (*mangled)++;
2140 string_prepend (&decl, "&");
2141 break;
2142
5d644692 2143 /* An array */
a3184468
JM
2144 case 'A':
2145 {
2146 const char *p = ++(*mangled);
2147
2148 string_prepend (&decl, "(");
2149 string_append (&decl, ")[");
2150 /* Copy anything up until the next underscore (the size of the
2151 array). */
2152 while (**mangled && **mangled != '_')
2153 ++(*mangled);
2154 if (**mangled == '_')
2155 {
2156 string_appendn (&decl, p, *mangled - p);
2157 string_append (&decl, "]");
2158 *mangled += 1;
2159 }
2160 else
2161 success = 0;
2162 break;
2163 }
2164
2165 /* A back reference to a previously seen type */
2166 case 'T':
2167 (*mangled)++;
2168 if (!get_count (mangled, &n) || n >= work -> ntypes)
2169 {
2170 success = 0;
2171 }
2172 else
2173 {
2174 remembered_type = work -> typevec[n];
2175 mangled = &remembered_type;
2176 }
2177 break;
2178
5d644692 2179 /* A function */
a3184468
JM
2180 case 'F':
2181 (*mangled)++;
2182 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2183 {
2184 string_prepend (&decl, "(");
2185 string_append (&decl, ")");
2186 }
2187 /* After picking off the function args, we expect to either find the
2188 function return type (preceded by an '_') or the end of the
0f41302f 2189 string. */
a3184468
JM
2190 if (!demangle_args (work, mangled, &decl)
2191 || (**mangled != '_' && **mangled != '\0'))
2192 {
2193 success = 0;
2194 }
2195 if (success && (**mangled == '_'))
2196 {
2197 (*mangled)++;
2198 }
2199 break;
2200
2201 case 'M':
2202 case 'O':
2203 {
2204 constp = 0;
2205 volatilep = 0;
2206
2207 member = **mangled == 'M';
2208 (*mangled)++;
5d644692 2209 if (!isdigit (**mangled) && **mangled != 't')
a3184468
JM
2210 {
2211 success = 0;
2212 break;
2213 }
5d644692 2214
a3184468 2215 string_append (&decl, ")");
a29f4129 2216 string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::");
5d644692
MS
2217 if (isdigit (**mangled))
2218 {
2219 n = consume_count (mangled);
2220 if (strlen (*mangled) < n)
2221 {
2222 success = 0;
2223 break;
2224 }
2225 string_prependn (&decl, *mangled, n);
2226 *mangled += n;
2227 }
2228 else
2229 {
2230 string temp;
2231 string_init (&temp);
37f6b6bf 2232 success = demangle_template (work, mangled, &temp, NULL, 1);
5d644692
MS
2233 if (success)
2234 {
2235 string_prependn (&decl, temp.b, temp.p - temp.b);
2236 string_clear (&temp);
2237 }
2238 else
2239 break;
2240 }
a3184468 2241 string_prepend (&decl, "(");
a3184468
JM
2242 if (member)
2243 {
2244 if (**mangled == 'C')
2245 {
2246 (*mangled)++;
2247 constp = 1;
2248 }
2249 if (**mangled == 'V')
2250 {
2251 (*mangled)++;
2252 volatilep = 1;
2253 }
2254 if (*(*mangled)++ != 'F')
2255 {
2256 success = 0;
2257 break;
2258 }
2259 }
2260 if ((member && !demangle_args (work, mangled, &decl))
2261 || **mangled != '_')
2262 {
2263 success = 0;
2264 break;
2265 }
2266 (*mangled)++;
2267 if (! PRINT_ANSI_QUALIFIERS)
2268 {
2269 break;
2270 }
2271 if (constp)
2272 {
2273 APPEND_BLANK (&decl);
2274 string_append (&decl, "const");
2275 }
2276 if (volatilep)
2277 {
2278 APPEND_BLANK (&decl);
2279 string_append (&decl, "volatile");
2280 }
2281 break;
2282 }
2283 case 'G':
5d644692
MS
2284 (*mangled)++;
2285 break;
a3184468
JM
2286
2287 case 'C':
2288 (*mangled)++;
5d644692
MS
2289 /*
2290 if ((*mangled)[1] == 'P')
a3184468 2291 {
5d644692
MS
2292 */
2293 if (PRINT_ANSI_QUALIFIERS)
2294 {
2295 if (!STRING_EMPTY (&decl))
a3184468 2296 {
5d644692 2297 string_prepend (&decl, " ");
a3184468 2298 }
5d644692 2299 string_prepend (&decl, "const");
a3184468 2300 }
5d644692
MS
2301 break;
2302 /*
2303 }
2304 */
a3184468
JM
2305
2306 /* fall through */
2307 default:
2308 done = 1;
2309 break;
2310 }
2311 }
2312
2313 switch (**mangled)
2314 {
0f41302f 2315 /* A qualified name, such as "Outer::Inner". */
5d644692
MS
2316 case 'Q':
2317 success = demangle_qualified (work, mangled, result, 0, 1);
2318 break;
a3184468 2319
37f6b6bf
MM
2320 case 'X':
2321 case 'Y':
2322 /* A template parm. We substitute the corresponding argument. */
2323 {
2324 int idx;
2325 int lvl;
2326
2327 (*mangled)++;
2328 idx = consume_count_with_underscores (mangled);
2329
2330 if (idx == -1
2331 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2332 || consume_count_with_underscores (mangled) == -1)
2333 {
2334 success = 0;
2335 break;
2336 }
2337
2338 if (work->tmpl_argvec)
2339 string_append (result, work->tmpl_argvec[idx]);
2340 else
2341 {
2342 char buf[10];
2343 sprintf(buf, "T%d", idx);
2344 string_append (result, buf);
2345 }
2346
2347 success = 1;
2348 }
2349 break;
2350
5d644692
MS
2351 default:
2352 success = demangle_fund_type (work, mangled, result);
2353 break;
a3184468
JM
2354 }
2355
2356 if (success)
2357 {
2358 if (!STRING_EMPTY (&decl))
2359 {
2360 string_append (result, " ");
2361 string_appends (result, &decl);
2362 }
2363 }
2364 else
2365 {
2366 string_delete (result);
2367 }
2368 string_delete (&decl);
2369 return (success);
2370}
2371
2372/* Given a pointer to a type string that represents a fundamental type
2373 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2374 string in which the demangled output is being built in RESULT, and
2375 the WORK structure, decode the types and add them to the result.
2376
2377 For example:
2378
2379 "Ci" => "const int"
2380 "Sl" => "signed long"
2381 "CUs" => "const unsigned short"
2382
2383 */
2384
2385static int
2386demangle_fund_type (work, mangled, result)
2387 struct work_stuff *work;
2388 const char **mangled;
2389 string *result;
2390{
2391 int done = 0;
2392 int success = 1;
2393
0f41302f 2394 /* First pick off any type qualifiers. There can be more than one. */
a3184468
JM
2395
2396 while (!done)
2397 {
2398 switch (**mangled)
2399 {
5d644692
MS
2400 case 'C':
2401 (*mangled)++;
2402 if (PRINT_ANSI_QUALIFIERS)
2403 {
2404 APPEND_BLANK (result);
2405 string_append (result, "const");
2406 }
2407 break;
2408 case 'U':
2409 (*mangled)++;
2410 APPEND_BLANK (result);
2411 string_append (result, "unsigned");
2412 break;
2413 case 'S': /* signed char only */
2414 (*mangled)++;
2415 APPEND_BLANK (result);
2416 string_append (result, "signed");
2417 break;
2418 case 'V':
2419 (*mangled)++;
2420 if (PRINT_ANSI_QUALIFIERS)
2421 {
2422 APPEND_BLANK (result);
2423 string_append (result, "volatile");
2424 }
2425 break;
5ff660f0
BK
2426 case 'J':
2427 (*mangled)++;
2428 APPEND_BLANK (result);
e9a25f70 2429 string_append (result, "__complex");
5ff660f0 2430 break;
5d644692
MS
2431 default:
2432 done = 1;
2433 break;
a3184468
JM
2434 }
2435 }
2436
0f41302f 2437 /* Now pick off the fundamental type. There can be only one. */
a3184468
JM
2438
2439 switch (**mangled)
2440 {
5d644692
MS
2441 case '\0':
2442 case '_':
2443 break;
2444 case 'v':
2445 (*mangled)++;
2446 APPEND_BLANK (result);
2447 string_append (result, "void");
2448 break;
2449 case 'x':
2450 (*mangled)++;
2451 APPEND_BLANK (result);
2452 string_append (result, "long long");
2453 break;
2454 case 'l':
2455 (*mangled)++;
2456 APPEND_BLANK (result);
2457 string_append (result, "long");
2458 break;
2459 case 'i':
2460 (*mangled)++;
2461 APPEND_BLANK (result);
2462 string_append (result, "int");
2463 break;
2464 case 's':
2465 (*mangled)++;
2466 APPEND_BLANK (result);
2467 string_append (result, "short");
2468 break;
2469 case 'b':
2470 (*mangled)++;
2471 APPEND_BLANK (result);
2472 string_append (result, "bool");
2473 break;
2474 case 'c':
2475 (*mangled)++;
2476 APPEND_BLANK (result);
2477 string_append (result, "char");
2478 break;
2479 case 'w':
2480 (*mangled)++;
2481 APPEND_BLANK (result);
2482 string_append (result, "wchar_t");
2483 break;
2484 case 'r':
2485 (*mangled)++;
2486 APPEND_BLANK (result);
2487 string_append (result, "long double");
2488 break;
2489 case 'd':
2490 (*mangled)++;
2491 APPEND_BLANK (result);
2492 string_append (result, "double");
2493 break;
2494 case 'f':
2495 (*mangled)++;
2496 APPEND_BLANK (result);
2497 string_append (result, "float");
2498 break;
2499 case 'G':
2500 (*mangled)++;
2501 if (!isdigit (**mangled))
2502 {
a3184468 2503 success = 0;
5d644692 2504 break;
a3184468 2505 }
5d644692
MS
2506 /* fall through */
2507 /* An explicit type, such as "6mytype" or "7integer" */
2508 case '0':
2509 case '1':
2510 case '2':
2511 case '3':
2512 case '4':
2513 case '5':
2514 case '6':
2515 case '7':
2516 case '8':
2517 case '9':
2518 APPEND_BLANK (result);
2519 if (!demangle_class_name (work, mangled, result)) {
2520 --result->p;
a3184468 2521 success = 0;
a3184468 2522 }
5d644692
MS
2523 break;
2524 case 't':
37f6b6bf 2525 success = demangle_template(work,mangled, result, 0, 1);
5d644692
MS
2526 break;
2527 default:
2528 success = 0;
2529 break;
2530 }
a3184468
JM
2531
2532 return (success);
2533}
2534
2535/* `result' will be initialized in do_type; it will be freed on failure */
2536
2537static int
2538do_arg (work, mangled, result)
2539 struct work_stuff *work;
2540 const char **mangled;
2541 string *result;
2542{
2543 const char *start = *mangled;
2544
2545 if (!do_type (work, mangled, result))
2546 {
2547 return (0);
2548 }
2549 else
2550 {
2551 remember_type (work, start, *mangled - start);
2552 return (1);
2553 }
2554}
2555
2556static void
2557remember_type (work, start, len)
2558 struct work_stuff *work;
2559 const char *start;
2560 int len;
2561{
2562 char *tem;
2563
2564 if (work -> ntypes >= work -> typevec_size)
2565 {
2566 if (work -> typevec_size == 0)
2567 {
2568 work -> typevec_size = 3;
e3da301d
MS
2569 work -> typevec
2570 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
a3184468
JM
2571 }
2572 else
2573 {
2574 work -> typevec_size *= 2;
e3da301d
MS
2575 work -> typevec
2576 = (char **) xrealloc ((char *)work -> typevec,
2577 sizeof (char *) * work -> typevec_size);
a3184468
JM
2578 }
2579 }
2580 tem = xmalloc (len + 1);
2581 memcpy (tem, start, len);
2582 tem[len] = '\0';
2583 work -> typevec[work -> ntypes++] = tem;
2584}
2585
0f41302f 2586/* Forget the remembered types, but not the type vector itself. */
a3184468
JM
2587
2588static void
2589forget_types (work)
2590 struct work_stuff *work;
2591{
2592 int i;
2593
2594 while (work -> ntypes > 0)
2595 {
2596 i = --(work -> ntypes);
2597 if (work -> typevec[i] != NULL)
2598 {
2599 free (work -> typevec[i]);
2600 work -> typevec[i] = NULL;
2601 }
2602 }
2603}
2604
2605/* Process the argument list part of the signature, after any class spec
2606 has been consumed, as well as the first 'F' character (if any). For
2607 example:
2608
2609 "__als__3fooRT0" => process "RT0"
2610 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2611
2612 DECLP must be already initialised, usually non-empty. It won't be freed
2613 on failure.
2614
2615 Note that g++ differs significantly from ARM and lucid style mangling
2616 with regards to references to previously seen types. For example, given
2617 the source fragment:
2618
2619 class foo {
2620 public:
2621 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2622 };
2623
2624 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2625 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2626
2627 g++ produces the names:
2628
2629 __3fooiRT0iT2iT2
2630 foo__FiR3fooiT1iT1
2631
2632 while lcc (and presumably other ARM style compilers as well) produces:
2633
2634 foo__FiR3fooT1T2T1T2
2635 __ct__3fooFiR3fooT1T2T1T2
2636
2637 Note that g++ bases it's type numbers starting at zero and counts all
2638 previously seen types, while lucid/ARM bases it's type numbers starting
2639 at one and only considers types after it has seen the 'F' character
2640 indicating the start of the function args. For lucid/ARM style, we
2641 account for this difference by discarding any previously seen types when
2642 we see the 'F' character, and subtracting one from the type number
2643 reference.
2644
2645 */
2646
2647static int
2648demangle_args (work, mangled, declp)
2649 struct work_stuff *work;
2650 const char **mangled;
2651 string *declp;
2652{
2653 string arg;
2654 int need_comma = 0;
2655 int r;
2656 int t;
2657 const char *tem;
2658 char temptype;
2659
2660 if (PRINT_ARG_TYPES)
2661 {
2662 string_append (declp, "(");
2663 if (**mangled == '\0')
2664 {
2665 string_append (declp, "void");
2666 }
2667 }
2668
2669 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2670 {
2671 if ((**mangled == 'N') || (**mangled == 'T'))
2672 {
2673 temptype = *(*mangled)++;
2674
2675 if (temptype == 'N')
2676 {
2677 if (!get_count (mangled, &r))
2678 {
2679 return (0);
2680 }
2681 }
2682 else
2683 {
2684 r = 1;
2685 }
2686 if (ARM_DEMANGLING && work -> ntypes >= 10)
2687 {
2688 /* If we have 10 or more types we might have more than a 1 digit
2689 index so we'll have to consume the whole count here. This
ddd5a7c1 2690 will lose if the next thing is a type name preceded by a
a3184468
JM
2691 count but it's impossible to demangle that case properly
2692 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
a3184468
JM
2693 Pc, ...)" or "(..., type12, char *, ...)" */
2694 if ((t = consume_count(mangled)) == 0)
2695 {
2696 return (0);
2697 }
2698 }
2699 else
2700 {
2701 if (!get_count (mangled, &t))
2702 {
2703 return (0);
2704 }
2705 }
2706 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2707 {
2708 t--;
2709 }
2710 /* Validate the type index. Protect against illegal indices from
0f41302f 2711 malformed type strings. */
a3184468
JM
2712 if ((t < 0) || (t >= work -> ntypes))
2713 {
2714 return (0);
2715 }
2716 while (--r >= 0)
2717 {
2718 tem = work -> typevec[t];
2719 if (need_comma && PRINT_ARG_TYPES)
2720 {
2721 string_append (declp, ", ");
2722 }
2723 if (!do_arg (work, &tem, &arg))
2724 {
2725 return (0);
2726 }
2727 if (PRINT_ARG_TYPES)
2728 {
2729 string_appends (declp, &arg);
2730 }
2731 string_delete (&arg);
2732 need_comma = 1;
2733 }
2734 }
2735 else
2736 {
2737 if (need_comma & PRINT_ARG_TYPES)
2738 {
2739 string_append (declp, ", ");
2740 }
2741 if (!do_arg (work, mangled, &arg))
2742 {
2743 return (0);
2744 }
2745 if (PRINT_ARG_TYPES)
2746 {
2747 string_appends (declp, &arg);
2748 }
2749 string_delete (&arg);
2750 need_comma = 1;
2751 }
2752 }
2753
2754 if (**mangled == 'e')
2755 {
2756 (*mangled)++;
2757 if (PRINT_ARG_TYPES)
2758 {
2759 if (need_comma)
2760 {
2761 string_append (declp, ",");
2762 }
2763 string_append (declp, "...");
2764 }
2765 }
2766
2767 if (PRINT_ARG_TYPES)
2768 {
2769 string_append (declp, ")");
2770 }
2771 return (1);
2772}
2773
2774static void
2775demangle_function_name (work, mangled, declp, scan)
2776 struct work_stuff *work;
2777 const char **mangled;
2778 string *declp;
2779 const char *scan;
2780{
2781 int i;
2782 int len;
2783 string type;
2784 const char *tem;
2785
2786 string_appendn (declp, (*mangled), scan - (*mangled));
2787 string_need (declp, 1);
2788 *(declp -> p) = '\0';
2789
2790 /* Consume the function name, including the "__" separating the name
2791 from the signature. We are guaranteed that SCAN points to the
0f41302f 2792 separator. */
a3184468
JM
2793
2794 (*mangled) = scan + 2;
2795
2796 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2797 {
2798
2799 /* See if we have an ARM style constructor or destructor operator.
2800 If so, then just record it, clear the decl, and return.
2801 We can't build the actual constructor/destructor decl until later,
0f41302f 2802 when we recover the class name from the signature. */
a3184468
JM
2803
2804 if (strcmp (declp -> b, "__ct") == 0)
2805 {
2806 work -> constructor += 1;
2807 string_clear (declp);
2808 return;
2809 }
2810 else if (strcmp (declp -> b, "__dt") == 0)
2811 {
2812 work -> destructor += 1;
2813 string_clear (declp);
2814 return;
2815 }
2816 }
2817
2818 if (declp->p - declp->b >= 3
2819 && declp->b[0] == 'o'
2820 && declp->b[1] == 'p'
2821 && strchr (cplus_markers, declp->b[2]) != NULL)
2822 {
2823 /* see if it's an assignment expression */
2824 if (declp->p - declp->b >= 10 /* op$assign_ */
2825 && memcmp (declp->b + 3, "assign_", 7) == 0)
2826 {
2827 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2828 {
2829 len = declp->p - declp->b - 10;
2830 if (strlen (optable[i].in) == len
2831 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2832 {
2833 string_clear (declp);
2834 string_append (declp, "operator");
2835 string_append (declp, optable[i].out);
2836 string_append (declp, "=");
2837 break;
2838 }
2839 }
2840 }
2841 else
2842 {
2843 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2844 {
2845 int len = declp->p - declp->b - 3;
2846 if (strlen (optable[i].in) == len
2847 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2848 {
2849 string_clear (declp);
2850 string_append (declp, "operator");
2851 string_append (declp, optable[i].out);
2852 break;
2853 }
2854 }
2855 }
2856 }
2857 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2858 && strchr (cplus_markers, declp->b[4]) != NULL)
2859 {
2860 /* type conversion operator */
2861 tem = declp->b + 5;
2862 if (do_type (work, &tem, &type))
2863 {
2864 string_clear (declp);
2865 string_append (declp, "operator ");
2866 string_appends (declp, &type);
2867 string_delete (&type);
2868 }
2869 }
2870 else if (declp->b[0] == '_' && declp->b[1] == '_'
5d644692 2871 && declp->b[2] == 'o' && declp->b[3] == 'p')
a3184468
JM
2872 {
2873 /* ANSI. */
2874 /* type conversion operator. */
2875 tem = declp->b + 4;
2876 if (do_type (work, &tem, &type))
2877 {
2878 string_clear (declp);
2879 string_append (declp, "operator ");
2880 string_appends (declp, &type);
2881 string_delete (&type);
2882 }
2883 }
2884 else if (declp->b[0] == '_' && declp->b[1] == '_'
2885 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2886 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2887 {
2888 if (declp->b[4] == '\0')
2889 {
2890 /* Operator. */
2891 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2892 {
2893 if (strlen (optable[i].in) == 2
2894 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2895 {
2896 string_clear (declp);
2897 string_append (declp, "operator");
2898 string_append (declp, optable[i].out);
2899 break;
2900 }
2901 }
2902 }
2903 else
2904 {
2905 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2906 {
0f41302f 2907 /* Assignment. */
a3184468
JM
2908 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2909 {
2910 if (strlen (optable[i].in) == 3
2911 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2912 {
2913 string_clear (declp);
2914 string_append (declp, "operator");
2915 string_append (declp, optable[i].out);
2916 break;
2917 }
2918 }
2919 }
2920 }
2921 }
2922}
2923
2924/* a mini string-handling package */
2925
2926static void
2927string_need (s, n)
2928 string *s;
2929 int n;
2930{
2931 int tem;
2932
2933 if (s->b == NULL)
2934 {
2935 if (n < 32)
2936 {
2937 n = 32;
2938 }
2939 s->p = s->b = xmalloc (n);
2940 s->e = s->b + n;
2941 }
2942 else if (s->e - s->p < n)
2943 {
2944 tem = s->p - s->b;
2945 n += tem;
2946 n *= 2;
2947 s->b = xrealloc (s->b, n);
2948 s->p = s->b + tem;
2949 s->e = s->b + n;
2950 }
2951}
2952
2953static void
2954string_delete (s)
2955 string *s;
2956{
2957 if (s->b != NULL)
2958 {
2959 free (s->b);
2960 s->b = s->e = s->p = NULL;
2961 }
2962}
2963
2964static void
2965string_init (s)
2966 string *s;
2967{
2968 s->b = s->p = s->e = NULL;
2969}
2970
2971static void
2972string_clear (s)
2973 string *s;
2974{
2975 s->p = s->b;
2976}
2977
2978#if 0
2979
2980static int
2981string_empty (s)
2982 string *s;
2983{
2984 return (s->b == s->p);
2985}
2986
2987#endif
2988
2989static void
2990string_append (p, s)
2991 string *p;
2992 const char *s;
2993{
2994 int n;
2995 if (s == NULL || *s == '\0')
2996 return;
2997 n = strlen (s);
2998 string_need (p, n);
2999 memcpy (p->p, s, n);
3000 p->p += n;
3001}
3002
3003static void
3004string_appends (p, s)
3005 string *p, *s;
3006{
3007 int n;
3008
3009 if (s->b != s->p)
3010 {
3011 n = s->p - s->b;
3012 string_need (p, n);
3013 memcpy (p->p, s->b, n);
3014 p->p += n;
3015 }
3016}
3017
3018static void
3019string_appendn (p, s, n)
3020 string *p;
3021 const char *s;
3022 int n;
3023{
3024 if (n != 0)
3025 {
3026 string_need (p, n);
3027 memcpy (p->p, s, n);
3028 p->p += n;
3029 }
3030}
3031
3032static void
3033string_prepend (p, s)
3034 string *p;
3035 const char *s;
3036{
3037 if (s != NULL && *s != '\0')
3038 {
3039 string_prependn (p, s, strlen (s));
3040 }
3041}
3042
3043static void
3044string_prepends (p, s)
3045 string *p, *s;
3046{
3047 if (s->b != s->p)
3048 {
3049 string_prependn (p, s->b, s->p - s->b);
3050 }
3051}
3052
3053static void
3054string_prependn (p, s, n)
3055 string *p;
3056 const char *s;
3057 int n;
3058{
3059 char *q;
3060
3061 if (n != 0)
3062 {
3063 string_need (p, n);
3064 for (q = p->p - 1; q >= p->b; q--)
3065 {
3066 q[n] = q[0];
3067 }
3068 memcpy (p->b, s, n);
3069 p->p += n;
3070 }
3071}
3072
3073/* To generate a standalone demangler program for testing purposes,
3074 just compile and link this file with -DMAIN and libiberty.a. When
3075 run, it demangles each command line arg, or each stdin string, and
0f41302f 3076 prints the result on stdout. */
a3184468
JM
3077
3078#ifdef MAIN
3079
a29f4129
PB
3080#include "getopt.h"
3081
3082static char *program_name;
3083static char *program_version = VERSION;
3084static int flags = DMGL_PARAMS | DMGL_ANSI;
3085
3086static void demangle_it PARAMS ((char *));
3087static void usage PARAMS ((FILE *, int));
3088static void fatal PARAMS ((char *));
3089
a3184468
JM
3090static void
3091demangle_it (mangled_name)
5d644692 3092 char *mangled_name;
a3184468
JM
3093{
3094 char *result;
3095
a29f4129 3096 result = cplus_demangle (mangled_name, flags);
a3184468
JM
3097 if (result == NULL)
3098 {
3099 printf ("%s\n", mangled_name);
3100 }
3101 else
3102 {
3103 printf ("%s\n", result);
3104 free (result);
3105 }
3106}
3107
a3184468
JM
3108static void
3109usage (stream, status)
3110 FILE *stream;
3111 int status;
3112{
3113 fprintf (stream, "\
3114Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
5d644692
MS
3115 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3116 [--help] [--version] [arg...]\n",
a3184468
JM
3117 program_name);
3118 exit (status);
3119}
3120
3121#define MBUF_SIZE 512
3122char mbuffer[MBUF_SIZE];
3123
0f41302f 3124/* Defined in the automatically-generated underscore.c. */
04f41951 3125extern int prepends_underscore;
a3184468
JM
3126
3127int strip_underscore = 0;
3128
3129static struct option long_options[] = {
3130 {"strip-underscores", no_argument, 0, '_'},
3131 {"format", required_argument, 0, 's'},
3132 {"help", no_argument, 0, 'h'},
a29f4129 3133 {"java", no_argument, 0, 'j'},
a3184468
JM
3134 {"no-strip-underscores", no_argument, 0, 'n'},
3135 {"version", no_argument, 0, 'v'},
3136 {0, no_argument, 0, 0}
3137};
3138
956d6950
JL
3139/* More 'friendly' abort that prints the line and file.
3140 config.h can #define abort fancy_abort if you like that sort of thing. */
3141
3142void
3143fancy_abort ()
3144{
3145 fatal ("Internal gcc abort.");
3146}
3147
a3184468
JM
3148int
3149main (argc, argv)
3150 int argc;
3151 char **argv;
3152{
3153 char *result;
3154 int c;
3155
3156 program_name = argv[0];
3157
3158 strip_underscore = prepends_underscore;
3159
04f41951 3160 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
a3184468
JM
3161 {
3162 switch (c)
3163 {
5d644692
MS
3164 case '?':
3165 usage (stderr, 1);
3166 break;
3167 case 'h':
3168 usage (stdout, 0);
3169 case 'n':
3170 strip_underscore = 0;
3171 break;
3172 case 'v':
3173 printf ("GNU %s version %s\n", program_name, program_version);
3174 exit (0);
3175 case '_':
3176 strip_underscore = 1;
3177 break;
a29f4129
PB
3178 case 'j':
3179 flags |= DMGL_JAVA;
3180 break;
5d644692
MS
3181 case 's':
3182 if (strcmp (optarg, "gnu") == 0)
3183 {
3184 current_demangling_style = gnu_demangling;
3185 }
3186 else if (strcmp (optarg, "lucid") == 0)
3187 {
3188 current_demangling_style = lucid_demangling;
3189 }
3190 else if (strcmp (optarg, "arm") == 0)
3191 {
3192 current_demangling_style = arm_demangling;
3193 }
3194 else
3195 {
3196 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3197 program_name, optarg);
3198 exit (1);
3199 }
3200 break;
a3184468
JM
3201 }
3202 }
3203
3204 if (optind < argc)
3205 {
3206 for ( ; optind < argc; optind++)
3207 {
3208 demangle_it (argv[optind]);
3209 }
3210 }
3211 else
3212 {
3213 for (;;)
3214 {
3215 int i = 0;
3216 c = getchar ();
0f41302f 3217 /* Try to read a label. */
a3184468
JM
3218 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3219 {
3220 if (i >= MBUF_SIZE-1)
3221 break;
3222 mbuffer[i++] = c;
3223 c = getchar ();
3224 }
3225 if (i > 0)
3226 {
3227 int skip_first = 0;
3228
3229 if (mbuffer[0] == '.')
3230 ++skip_first;
3231 if (strip_underscore && mbuffer[skip_first] == '_')
3232 ++skip_first;
3233
3234 if (skip_first > i)
3235 skip_first = i;
3236
3237 mbuffer[i] = 0;
3238
a29f4129 3239 result = cplus_demangle (mbuffer + skip_first, flags);
a3184468
JM
3240 if (result)
3241 {
3242 if (mbuffer[0] == '.')
3243 putc ('.', stdout);
3244 fputs (result, stdout);
3245 free (result);
3246 }
3247 else
3248 fputs (mbuffer, stdout);
3249
3250 fflush (stdout);
3251 }
3252 if (c == EOF)
3253 break;
3254 putchar (c);
3255 }
3256 }
3257
3258 exit (0);
3259}
3260
3261static void
3262fatal (str)
3263 char *str;
3264{
3265 fprintf (stderr, "%s: %s\n", program_name, str);
3266 exit (1);
3267}
3268
3269char * malloc ();
3270char * realloc ();
3271
3272char *
3273xmalloc (size)
3274 unsigned size;
3275{
3276 register char *value = (char *) malloc (size);
3277 if (value == 0)
3278 fatal ("virtual memory exhausted");
3279 return value;
3280}
3281
3282char *
3283xrealloc (ptr, size)
3284 char *ptr;
3285 unsigned size;
3286{
3287 register char *value = (char *) realloc (ptr, size);
3288 if (value == 0)
3289 fatal ("virtual memory exhausted");
3290 return value;
3291}
3292#endif /* main */
This page took 0.500145 seconds and 5 git commands to generate.