update copyright
[official-gcc.git] / libiberty / cplus-dem.c
blobba53bc4c118239f5a54530e9658c2058ed06a8d0
1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 This file is part of the libiberty library.
7 Libiberty is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 Libiberty is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with libiberty; see the file COPYING.LIB. If
19 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
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
26 available memory. */
28 /* This file lives in both GCC and libiberty. When making changes, please
29 try not to break either. */
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
35 #include <ctype.h>
36 #include <sys/types.h>
37 #include <string.h>
38 #include <stdio.h>
40 #ifdef HAVE_STDLIB_H
41 #include <stdlib.h>
42 #else
43 char * malloc ();
44 char * realloc ();
45 #endif
47 #include <demangle.h>
48 #undef CURRENT_DEMANGLING_STYLE
49 #define CURRENT_DEMANGLING_STYLE work->options
51 extern char *xmalloc PARAMS((unsigned));
52 extern char *xrealloc PARAMS((char *, unsigned));
54 static const char *mystrstr PARAMS ((const char *, const char *));
56 static const char *
57 mystrstr (s1, s2)
58 const char *s1, *s2;
60 register const char *p = s1;
61 register int len = strlen (s2);
63 for (; (p = strchr (p, *s2)) != 0; p++)
65 if (strncmp (p, s2, len) == 0)
67 return (p);
70 return (0);
73 /* In order to allow a single demangler executable to demangle strings
74 using various common values of CPLUS_MARKER, as well as any specific
75 one set at compile time, we maintain a string containing all the
76 commonly used ones, and check to see if the marker we are looking for
77 is in that string. CPLUS_MARKER is usually '$' on systems where the
78 assembler can deal with that. Where the assembler can't, it's usually
79 '.' (but on many systems '.' is used for other things). We put the
80 current defined CPLUS_MARKER first (which defaults to '$'), followed
81 by the next most common value, followed by an explicit '$' in case
82 the value of CPLUS_MARKER is not '$'.
84 We could avoid this if we could just get g++ to tell us what the actual
85 cplus marker character is as part of the debug information, perhaps by
86 ensuring that it is the character that terminates the gcc<n>_compiled
87 marker symbol (FIXME). */
89 #if !defined (CPLUS_MARKER)
90 #define CPLUS_MARKER '$'
91 #endif
93 enum demangling_styles current_demangling_style = gnu_demangling;
95 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
97 void
98 set_cplus_marker_for_demangling (ch)
99 int ch;
101 cplus_markers[0] = ch;
104 typedef struct string /* Beware: these aren't required to be */
105 { /* '\0' terminated. */
106 char *b; /* pointer to start of string */
107 char *p; /* pointer after last character */
108 char *e; /* pointer after end of allocated space */
109 } string;
111 /* Stuff that is shared between sub-routines.
112 Using a shared structure allows cplus_demangle to be reentrant. */
114 struct work_stuff
116 int options;
117 char **typevec;
118 char **ktypevec;
119 char **btypevec;
120 int numk;
121 int numb;
122 int ksize;
123 int bsize;
124 int ntypes;
125 int typevec_size;
126 int constructor;
127 int destructor;
128 int static_type; /* A static member function */
129 int const_type; /* A const member function */
130 int volatile_type; /* A volatile member function */
131 int dllimported; /* Symbol imported from a PE DLL */
132 char **tmpl_argvec; /* Template function arguments. */
133 int ntmpl_args; /* The number of template function arguments. */
134 int forgetting_types; /* Nonzero if we are not remembering the types
135 we see. */
136 string* previous_argument; /* The last function argument demangled. */
137 int nrepeats; /* The number of times to repeat the previous
138 argument. */
141 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
142 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
144 static const struct optable
146 const char *in;
147 const char *out;
148 int flags;
149 } optable[] = {
150 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
151 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
152 {"new", " new", 0}, /* old (1.91, and 1.x) */
153 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
154 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
155 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
156 {"as", "=", DMGL_ANSI}, /* ansi */
157 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
158 {"eq", "==", DMGL_ANSI}, /* old, ansi */
159 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
160 {"gt", ">", DMGL_ANSI}, /* old, ansi */
161 {"le", "<=", DMGL_ANSI}, /* old, ansi */
162 {"lt", "<", DMGL_ANSI}, /* old, ansi */
163 {"plus", "+", 0}, /* old */
164 {"pl", "+", DMGL_ANSI}, /* ansi */
165 {"apl", "+=", DMGL_ANSI}, /* ansi */
166 {"minus", "-", 0}, /* old */
167 {"mi", "-", DMGL_ANSI}, /* ansi */
168 {"ami", "-=", DMGL_ANSI}, /* ansi */
169 {"mult", "*", 0}, /* old */
170 {"ml", "*", DMGL_ANSI}, /* ansi */
171 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
172 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
173 {"convert", "+", 0}, /* old (unary +) */
174 {"negate", "-", 0}, /* old (unary -) */
175 {"trunc_mod", "%", 0}, /* old */
176 {"md", "%", DMGL_ANSI}, /* ansi */
177 {"amd", "%=", DMGL_ANSI}, /* ansi */
178 {"trunc_div", "/", 0}, /* old */
179 {"dv", "/", DMGL_ANSI}, /* ansi */
180 {"adv", "/=", DMGL_ANSI}, /* ansi */
181 {"truth_andif", "&&", 0}, /* old */
182 {"aa", "&&", DMGL_ANSI}, /* ansi */
183 {"truth_orif", "||", 0}, /* old */
184 {"oo", "||", DMGL_ANSI}, /* ansi */
185 {"truth_not", "!", 0}, /* old */
186 {"nt", "!", DMGL_ANSI}, /* ansi */
187 {"postincrement","++", 0}, /* old */
188 {"pp", "++", DMGL_ANSI}, /* ansi */
189 {"postdecrement","--", 0}, /* old */
190 {"mm", "--", DMGL_ANSI}, /* ansi */
191 {"bit_ior", "|", 0}, /* old */
192 {"or", "|", DMGL_ANSI}, /* ansi */
193 {"aor", "|=", DMGL_ANSI}, /* ansi */
194 {"bit_xor", "^", 0}, /* old */
195 {"er", "^", DMGL_ANSI}, /* ansi */
196 {"aer", "^=", DMGL_ANSI}, /* ansi */
197 {"bit_and", "&", 0}, /* old */
198 {"ad", "&", DMGL_ANSI}, /* ansi */
199 {"aad", "&=", DMGL_ANSI}, /* ansi */
200 {"bit_not", "~", 0}, /* old */
201 {"co", "~", DMGL_ANSI}, /* ansi */
202 {"call", "()", 0}, /* old */
203 {"cl", "()", DMGL_ANSI}, /* ansi */
204 {"alshift", "<<", 0}, /* old */
205 {"ls", "<<", DMGL_ANSI}, /* ansi */
206 {"als", "<<=", DMGL_ANSI}, /* ansi */
207 {"arshift", ">>", 0}, /* old */
208 {"rs", ">>", DMGL_ANSI}, /* ansi */
209 {"ars", ">>=", DMGL_ANSI}, /* ansi */
210 {"component", "->", 0}, /* old */
211 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
212 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
213 {"indirect", "*", 0}, /* old */
214 {"method_call", "->()", 0}, /* old */
215 {"addr", "&", 0}, /* old (unary &) */
216 {"array", "[]", 0}, /* old */
217 {"vc", "[]", DMGL_ANSI}, /* ansi */
218 {"compound", ", ", 0}, /* old */
219 {"cm", ", ", DMGL_ANSI}, /* ansi */
220 {"cond", "?:", 0}, /* old */
221 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
222 {"max", ">?", 0}, /* old */
223 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
224 {"min", "<?", 0}, /* old */
225 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
226 {"nop", "", 0}, /* old (for operator=) */
227 {"rm", "->*", DMGL_ANSI}, /* ansi */
228 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
231 /* These values are used to indicate the various type varieties.
232 They are all non-zero so that they can be used as `success'
233 values. */
234 typedef enum type_kind_t
236 tk_none,
237 tk_pointer,
238 tk_integral,
239 tk_bool,
240 tk_char,
241 tk_real
242 } type_kind_t;
244 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
245 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
246 string_prepend(str, " ");}
247 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
248 string_append(str, " ");}
249 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
251 /* The scope separator appropriate for the language being demangled. */
252 #define SCOPE_STRING(work) "::"
254 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
255 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
257 /* Prototypes for local functions */
259 static char *
260 mop_up PARAMS ((struct work_stuff *, string *, int));
262 static void
263 squangle_mop_up PARAMS ((struct work_stuff *));
265 #if 0
266 static int
267 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
268 #endif
270 static char *
271 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
273 static int
274 demangle_template_template_parm PARAMS ((struct work_stuff *work,
275 const char **, string *));
277 static int
278 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
279 string *, int, int));
281 static int
282 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
283 const char **));
285 static void
286 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
288 static int
289 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
291 static int
292 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
293 int, int));
295 static int
296 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
298 static int
299 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
301 static int
302 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
304 static int
305 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
307 static int
308 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
310 static int
311 arm_special PARAMS ((const char **, string *));
313 static void
314 string_need PARAMS ((string *, int));
316 static void
317 string_delete PARAMS ((string *));
319 static void
320 string_init PARAMS ((string *));
322 static void
323 string_clear PARAMS ((string *));
325 #if 0
326 static int
327 string_empty PARAMS ((string *));
328 #endif
330 static void
331 string_append PARAMS ((string *, const char *));
333 static void
334 string_appends PARAMS ((string *, string *));
336 static void
337 string_appendn PARAMS ((string *, const char *, int));
339 static void
340 string_prepend PARAMS ((string *, const char *));
342 static void
343 string_prependn PARAMS ((string *, const char *, int));
345 static int
346 get_count PARAMS ((const char **, int *));
348 static int
349 consume_count PARAMS ((const char **));
351 static int
352 consume_count_with_underscores PARAMS ((const char**));
354 static int
355 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
357 static int
358 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
360 static int
361 do_type PARAMS ((struct work_stuff *, const char **, string *));
363 static int
364 do_arg PARAMS ((struct work_stuff *, const char **, string *));
366 static void
367 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
368 const char *));
370 static void
371 remember_type PARAMS ((struct work_stuff *, const char *, int));
373 static void
374 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
376 static int
377 register_Btype PARAMS ((struct work_stuff *));
379 static void
380 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
382 static void
383 forget_types PARAMS ((struct work_stuff *));
385 static void
386 forget_B_and_K_types PARAMS ((struct work_stuff *));
388 static void
389 string_prepends PARAMS ((string *, string *));
391 static int
392 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
393 string*, type_kind_t));
395 /* Translate count to integer, consuming tokens in the process.
396 Conversion terminates on the first non-digit character.
397 Trying to consume something that isn't a count results in
398 no consumption of input and a return of 0. */
400 static int
401 consume_count (type)
402 const char **type;
404 int count = 0;
406 while (isdigit (**type))
408 count *= 10;
409 count += **type - '0';
410 (*type)++;
412 return (count);
416 /* Like consume_count, but for counts that are preceded and followed
417 by '_' if they are greater than 10. Also, -1 is returned for
418 failure, since 0 can be a valid value. */
420 static int
421 consume_count_with_underscores (mangled)
422 const char **mangled;
424 int idx;
426 if (**mangled == '_')
428 (*mangled)++;
429 if (!isdigit (**mangled))
430 return -1;
432 idx = consume_count (mangled);
433 if (**mangled != '_')
434 /* The trailing underscore was missing. */
435 return -1;
437 (*mangled)++;
439 else
441 if (**mangled < '0' || **mangled > '9')
442 return -1;
444 idx = **mangled - '0';
445 (*mangled)++;
448 return idx;
452 cplus_demangle_opname (opname, result, options)
453 const char *opname;
454 char *result;
455 int options;
457 int len, len1, ret;
458 string type;
459 struct work_stuff work[1];
460 const char *tem;
462 len = strlen(opname);
463 result[0] = '\0';
464 ret = 0;
465 memset ((char *) work, 0, sizeof (work));
466 work->options = options;
468 if (opname[0] == '_' && opname[1] == '_'
469 && opname[2] == 'o' && opname[3] == 'p')
471 /* ANSI. */
472 /* type conversion operator. */
473 tem = opname + 4;
474 if (do_type (work, &tem, &type))
476 strcat (result, "operator ");
477 strncat (result, type.b, type.p - type.b);
478 string_delete (&type);
479 ret = 1;
482 else if (opname[0] == '_' && opname[1] == '_'
483 && opname[2] >= 'a' && opname[2] <= 'z'
484 && opname[3] >= 'a' && opname[3] <= 'z')
486 if (opname[4] == '\0')
488 /* Operator. */
489 size_t i;
490 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
492 if (strlen (optable[i].in) == 2
493 && memcmp (optable[i].in, opname + 2, 2) == 0)
495 strcat (result, "operator");
496 strcat (result, optable[i].out);
497 ret = 1;
498 break;
502 else
504 if (opname[2] == 'a' && opname[5] == '\0')
506 /* Assignment. */
507 size_t i;
508 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
510 if (strlen (optable[i].in) == 3
511 && memcmp (optable[i].in, opname + 2, 3) == 0)
513 strcat (result, "operator");
514 strcat (result, optable[i].out);
515 ret = 1;
516 break;
522 else if (len >= 3
523 && opname[0] == 'o'
524 && opname[1] == 'p'
525 && strchr (cplus_markers, opname[2]) != NULL)
527 /* see if it's an assignment expression */
528 if (len >= 10 /* op$assign_ */
529 && memcmp (opname + 3, "assign_", 7) == 0)
531 size_t i;
532 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
534 len1 = len - 10;
535 if (strlen (optable[i].in) == len1
536 && memcmp (optable[i].in, opname + 10, len1) == 0)
538 strcat (result, "operator");
539 strcat (result, optable[i].out);
540 strcat (result, "=");
541 ret = 1;
542 break;
546 else
548 size_t i;
549 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
551 len1 = len - 3;
552 if (strlen (optable[i].in) == len1
553 && memcmp (optable[i].in, opname + 3, len1) == 0)
555 strcat (result, "operator");
556 strcat (result, optable[i].out);
557 ret = 1;
558 break;
563 else if (len >= 5 && memcmp (opname, "type", 4) == 0
564 && strchr (cplus_markers, opname[4]) != NULL)
566 /* type conversion operator */
567 tem = opname + 5;
568 if (do_type (work, &tem, &type))
570 strcat (result, "operator ");
571 strncat (result, type.b, type.p - type.b);
572 string_delete (&type);
573 ret = 1;
576 squangle_mop_up (work);
577 return ret;
580 /* Takes operator name as e.g. "++" and returns mangled
581 operator name (e.g. "postincrement_expr"), or NULL if not found.
583 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
584 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
586 const char *
587 cplus_mangle_opname (opname, options)
588 const char *opname;
589 int options;
591 size_t i;
592 int len;
594 len = strlen (opname);
595 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
597 if (strlen (optable[i].out) == len
598 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
599 && memcmp (optable[i].out, opname, len) == 0)
600 return optable[i].in;
602 return (0);
605 /* char *cplus_demangle (const char *mangled, int options)
607 If MANGLED is a mangled function name produced by GNU C++, then
608 a pointer to a malloced string giving a C++ representation
609 of the name will be returned; otherwise NULL will be returned.
610 It is the caller's responsibility to free the string which
611 is returned.
613 The OPTIONS arg may contain one or more of the following bits:
615 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
616 included.
617 DMGL_PARAMS Function parameters are included.
619 For example,
621 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
622 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
623 cplus_demangle ("foo__1Ai", 0) => "A::foo"
625 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
626 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
627 cplus_demangle ("foo__1Afe", 0) => "A::foo"
629 Note that any leading underscores, or other such characters prepended by
630 the compilation system, are presumed to have already been stripped from
631 MANGLED. */
633 char *
634 cplus_demangle (mangled, options)
635 const char *mangled;
636 int options;
638 char *ret;
639 struct work_stuff work[1];
640 memset ((char *) work, 0, sizeof (work));
641 work -> options = options;
642 if ((work -> options & DMGL_STYLE_MASK) == 0)
643 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
645 ret = internal_cplus_demangle (work, mangled);
646 squangle_mop_up (work);
647 return (ret);
651 /* This function performs most of what cplus_demangle use to do, but
652 to be able to demangle a name with a B, K or n code, we need to
653 have a longer term memory of what types have been seen. The original
654 now intializes and cleans up the squangle code info, while internal
655 calls go directly to this routine to avoid resetting that info. */
657 static char *
658 internal_cplus_demangle (work, mangled)
659 struct work_stuff *work;
660 const char *mangled;
663 string decl;
664 int success = 0;
665 char *demangled = NULL;
666 int s1,s2,s3,s4;
667 int saved_volatile_type;
668 s1 = work->constructor;
669 s2 = work->destructor;
670 s3 = work->static_type;
671 s4 = work->const_type;
672 saved_volatile_type = work->volatile_type;
673 work->constructor = work->destructor = 0;
674 work->static_type = work->const_type = 0;
675 work->volatile_type = 0;
676 work->dllimported = 0;
678 if ((mangled != NULL) && (*mangled != '\0'))
680 string_init (&decl);
682 /* First check to see if gnu style demangling is active and if the
683 string to be demangled contains a CPLUS_MARKER. If so, attempt to
684 recognize one of the gnu special forms rather than looking for a
685 standard prefix. In particular, don't worry about whether there
686 is a "__" string in the mangled string. Consider "_$_5__foo" for
687 example. */
689 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
691 success = gnu_special (work, &mangled, &decl);
693 if (!success)
695 success = demangle_prefix (work, &mangled, &decl);
697 if (success && (*mangled != '\0'))
699 success = demangle_signature (work, &mangled, &decl);
701 if (work->constructor == 2)
703 string_prepend (&decl, "global constructors keyed to ");
704 work->constructor = 0;
706 else if (work->destructor == 2)
708 string_prepend (&decl, "global destructors keyed to ");
709 work->destructor = 0;
711 else if (work->dllimported == 1)
713 string_prepend (&decl, "import stub for ");
714 work->dllimported = 0;
716 demangled = mop_up (work, &decl, success);
718 work->constructor = s1;
719 work->destructor = s2;
720 work->static_type = s3;
721 work->const_type = s4;
722 work->volatile_type = saved_volatile_type;
723 return (demangled);
727 /* Clear out and squangling related storage */
728 static void
729 squangle_mop_up (work)
730 struct work_stuff *work;
732 /* clean up the B and K type mangling types. */
733 forget_B_and_K_types (work);
734 if (work -> btypevec != NULL)
736 free ((char *) work -> btypevec);
738 if (work -> ktypevec != NULL)
740 free ((char *) work -> ktypevec);
744 /* Clear out any mangled storage */
746 static char *
747 mop_up (work, declp, success)
748 struct work_stuff *work;
749 string *declp;
750 int success;
752 char *demangled = NULL;
754 /* Discard the remembered types, if any. */
756 forget_types (work);
757 if (work -> typevec != NULL)
759 free ((char *) work -> typevec);
760 work -> typevec = NULL;
762 if (work->tmpl_argvec)
764 int i;
766 for (i = 0; i < work->ntmpl_args; i++)
767 if (work->tmpl_argvec[i])
768 free ((char*) work->tmpl_argvec[i]);
770 free ((char*) work->tmpl_argvec);
771 work->tmpl_argvec = NULL;
773 if (work->previous_argument)
775 string_delete (work->previous_argument);
776 free ((char*) work->previous_argument);
779 /* If demangling was successful, ensure that the demangled string is null
780 terminated and return it. Otherwise, free the demangling decl. */
782 if (!success)
784 string_delete (declp);
786 else
788 string_appendn (declp, "", 1);
789 demangled = declp -> b;
791 return (demangled);
796 LOCAL FUNCTION
798 demangle_signature -- demangle the signature part of a mangled name
800 SYNOPSIS
802 static int
803 demangle_signature (struct work_stuff *work, const char **mangled,
804 string *declp);
806 DESCRIPTION
808 Consume and demangle the signature portion of the mangled name.
810 DECLP is the string where demangled output is being built. At
811 entry it contains the demangled root name from the mangled name
812 prefix. I.E. either a demangled operator name or the root function
813 name. In some special cases, it may contain nothing.
815 *MANGLED points to the current unconsumed location in the mangled
816 name. As tokens are consumed and demangling is performed, the
817 pointer is updated to continuously point at the next token to
818 be consumed.
820 Demangling GNU style mangled names is nasty because there is no
821 explicit token that marks the start of the outermost function
822 argument list. */
824 static int
825 demangle_signature (work, mangled, declp)
826 struct work_stuff *work;
827 const char **mangled;
828 string *declp;
830 int success = 1;
831 int func_done = 0;
832 int expect_func = 0;
833 int expect_return_type = 0;
834 const char *oldmangled = NULL;
835 string trawname;
836 string tname;
838 while (success && (**mangled != '\0'))
840 switch (**mangled)
842 case 'Q':
843 oldmangled = *mangled;
844 success = demangle_qualified (work, mangled, declp, 1, 0);
845 if (success)
846 remember_type (work, oldmangled, *mangled - oldmangled);
847 if (AUTO_DEMANGLING || GNU_DEMANGLING)
848 expect_func = 1;
849 oldmangled = NULL;
850 break;
852 case 'K':
853 oldmangled = *mangled;
854 success = demangle_qualified (work, mangled, declp, 1, 0);
855 if (AUTO_DEMANGLING || GNU_DEMANGLING)
857 expect_func = 1;
859 oldmangled = NULL;
860 break;
862 case 'S':
863 /* Static member function */
864 if (oldmangled == NULL)
866 oldmangled = *mangled;
868 (*mangled)++;
869 work -> static_type = 1;
870 break;
872 case 'C':
873 case 'V':
874 if (**mangled == 'C')
875 work -> const_type = 1;
876 else
877 work->volatile_type = 1;
879 /* a qualified member function */
880 if (oldmangled == NULL)
881 oldmangled = *mangled;
882 (*mangled)++;
883 break;
885 case '0': case '1': case '2': case '3': case '4':
886 case '5': case '6': case '7': case '8': case '9':
887 if (oldmangled == NULL)
889 oldmangled = *mangled;
891 success = demangle_class (work, mangled, declp);
892 if (success)
894 remember_type (work, oldmangled, *mangled - oldmangled);
896 if (AUTO_DEMANGLING || GNU_DEMANGLING)
898 expect_func = 1;
900 oldmangled = NULL;
901 break;
903 case 'B':
905 string s;
906 success = do_type (work, mangled, &s);
907 if (success)
909 string_append (&s, SCOPE_STRING (work));
910 string_prepends (declp, &s);
912 oldmangled = NULL;
913 expect_func = 1;
915 break;
917 case 'F':
918 /* Function */
919 /* ARM style demangling includes a specific 'F' character after
920 the class name. For GNU style, it is just implied. So we can
921 safely just consume any 'F' at this point and be compatible
922 with either style. */
924 oldmangled = NULL;
925 func_done = 1;
926 (*mangled)++;
928 /* For lucid/ARM style we have to forget any types we might
929 have remembered up to this point, since they were not argument
930 types. GNU style considers all types seen as available for
931 back references. See comment in demangle_args() */
933 if (LUCID_DEMANGLING || ARM_DEMANGLING)
935 forget_types (work);
937 success = demangle_args (work, mangled, declp);
938 break;
940 case 't':
941 /* G++ Template */
942 string_init(&trawname);
943 string_init(&tname);
944 if (oldmangled == NULL)
946 oldmangled = *mangled;
948 success = demangle_template (work, mangled, &tname,
949 &trawname, 1, 1);
950 if (success)
952 remember_type (work, oldmangled, *mangled - oldmangled);
954 string_append (&tname, SCOPE_STRING (work));
956 string_prepends(declp, &tname);
957 if (work -> destructor & 1)
959 string_prepend (&trawname, "~");
960 string_appends (declp, &trawname);
961 work->destructor -= 1;
963 if ((work->constructor & 1) || (work->destructor & 1))
965 string_appends (declp, &trawname);
966 work->constructor -= 1;
968 string_delete(&trawname);
969 string_delete(&tname);
970 oldmangled = NULL;
971 expect_func = 1;
972 break;
974 case '_':
975 if (GNU_DEMANGLING && expect_return_type)
977 /* Read the return type. */
978 string return_type;
979 string_init (&return_type);
981 (*mangled)++;
982 success = do_type (work, mangled, &return_type);
983 APPEND_BLANK (&return_type);
985 string_prepends (declp, &return_type);
986 string_delete (&return_type);
987 break;
989 else
990 /* At the outermost level, we cannot have a return type specified,
991 so if we run into another '_' at this point we are dealing with
992 a mangled name that is either bogus, or has been mangled by
993 some algorithm we don't know how to deal with. So just
994 reject the entire demangling. */
995 success = 0;
996 break;
998 case 'H':
999 if (GNU_DEMANGLING)
1001 /* A G++ template function. Read the template arguments. */
1002 success = demangle_template (work, mangled, declp, 0, 0,
1004 if (!(work->constructor & 1))
1005 expect_return_type = 1;
1006 (*mangled)++;
1007 break;
1009 else
1010 /* fall through */
1013 default:
1014 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1016 /* Assume we have stumbled onto the first outermost function
1017 argument token, and start processing args. */
1018 func_done = 1;
1019 success = demangle_args (work, mangled, declp);
1021 else
1023 /* Non-GNU demanglers use a specific token to mark the start
1024 of the outermost function argument tokens. Typically 'F',
1025 for ARM-demangling, for example. So if we find something
1026 we are not prepared for, it must be an error. */
1027 success = 0;
1029 break;
1032 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1035 if (success && expect_func)
1037 func_done = 1;
1038 success = demangle_args (work, mangled, declp);
1039 /* Since template include the mangling of their return types,
1040 we must set expect_func to 0 so that we don't try do
1041 demangle more arguments the next time we get here. */
1042 expect_func = 0;
1046 if (success && !func_done)
1048 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1050 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1051 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1052 first case, and need to ensure that the '(void)' gets added to
1053 the current declp. Note that with ARM, the first case
1054 represents the name of a static data member 'foo::bar',
1055 which is in the current declp, so we leave it alone. */
1056 success = demangle_args (work, mangled, declp);
1059 if (success && work -> static_type && PRINT_ARG_TYPES)
1060 string_append (declp, " static");
1061 if (success && work -> const_type && PRINT_ARG_TYPES)
1062 string_append (declp, " const");
1063 else if (success && work->volatile_type && PRINT_ARG_TYPES)
1064 string_append (declp, " volatile");
1066 return (success);
1069 #if 0
1071 static int
1072 demangle_method_args (work, mangled, declp)
1073 struct work_stuff *work;
1074 const char **mangled;
1075 string *declp;
1077 int success = 0;
1079 if (work -> static_type)
1081 string_append (declp, *mangled + 1);
1082 *mangled += strlen (*mangled);
1083 success = 1;
1085 else
1087 success = demangle_args (work, mangled, declp);
1089 return (success);
1092 #endif
1094 static int
1095 demangle_template_template_parm (work, mangled, tname)
1096 struct work_stuff *work;
1097 const char **mangled;
1098 string *tname;
1100 int i;
1101 int r;
1102 int need_comma = 0;
1103 int success = 1;
1104 string temp;
1106 string_append (tname, "template <");
1107 /* get size of template parameter list */
1108 if (get_count (mangled, &r))
1110 for (i = 0; i < r; i++)
1112 if (need_comma)
1114 string_append (tname, ", ");
1117 /* Z for type parameters */
1118 if (**mangled == 'Z')
1120 (*mangled)++;
1121 string_append (tname, "class");
1123 /* z for template parameters */
1124 else if (**mangled == 'z')
1126 (*mangled)++;
1127 success =
1128 demangle_template_template_parm (work, mangled, tname);
1129 if (!success)
1131 break;
1134 else
1136 /* temp is initialized in do_type */
1137 success = do_type (work, mangled, &temp);
1138 if (success)
1140 string_appends (tname, &temp);
1142 string_delete(&temp);
1143 if (!success)
1145 break;
1148 need_comma = 1;
1152 if (tname->p[-1] == '>')
1153 string_append (tname, " ");
1154 string_append (tname, "> class");
1155 return (success);
1158 static int
1159 demangle_integral_value (work, mangled, s)
1160 struct work_stuff *work;
1161 const char** mangled;
1162 string* s;
1164 int success;
1166 if (**mangled == 'E')
1168 int need_operator = 0;
1170 success = 1;
1171 string_appendn (s, "(", 1);
1172 (*mangled)++;
1173 while (success && **mangled != 'W' && **mangled != '\0')
1175 if (need_operator)
1177 size_t i;
1178 size_t len;
1180 success = 0;
1182 len = strlen (*mangled);
1184 for (i = 0;
1185 i < sizeof (optable) / sizeof (optable [0]);
1186 ++i)
1188 size_t l = strlen (optable[i].in);
1190 if (l <= len
1191 && memcmp (optable[i].in, *mangled, l) == 0)
1193 string_appendn (s, " ", 1);
1194 string_append (s, optable[i].out);
1195 string_appendn (s, " ", 1);
1196 success = 1;
1197 (*mangled) += l;
1198 break;
1202 if (!success)
1203 break;
1205 else
1206 need_operator = 1;
1208 success = demangle_template_value_parm (work, mangled, s,
1209 tk_integral);
1212 if (**mangled != 'W')
1213 success = 0;
1214 else
1216 string_appendn (s, ")", 1);
1217 (*mangled)++;
1220 else if (**mangled == 'Q' || **mangled == 'K')
1221 success = demangle_qualified (work, mangled, s, 0, 1);
1222 else
1224 success = 0;
1226 if (**mangled == 'm')
1228 string_appendn (s, "-", 1);
1229 (*mangled)++;
1231 while (isdigit (**mangled))
1233 string_appendn (s, *mangled, 1);
1234 (*mangled)++;
1235 success = 1;
1239 return success;
1242 static int
1243 demangle_template_value_parm (work, mangled, s, tk)
1244 struct work_stuff *work;
1245 const char **mangled;
1246 string* s;
1247 type_kind_t tk;
1249 int success = 1;
1251 if (**mangled == 'Y')
1253 /* The next argument is a template parameter. */
1254 int idx;
1256 (*mangled)++;
1257 idx = consume_count_with_underscores (mangled);
1258 if (idx == -1
1259 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1260 || consume_count_with_underscores (mangled) == -1)
1261 return -1;
1262 if (work->tmpl_argvec)
1263 string_append (s, work->tmpl_argvec[idx]);
1264 else
1266 char buf[10];
1267 sprintf(buf, "T%d", idx);
1268 string_append (s, buf);
1271 else if (tk == tk_integral)
1272 success = demangle_integral_value (work, mangled, s);
1273 else if (tk == tk_char)
1275 char tmp[2];
1276 int val;
1277 if (**mangled == 'm')
1279 string_appendn (s, "-", 1);
1280 (*mangled)++;
1282 string_appendn (s, "'", 1);
1283 val = consume_count(mangled);
1284 if (val == 0)
1285 return -1;
1286 tmp[0] = (char)val;
1287 tmp[1] = '\0';
1288 string_appendn (s, &tmp[0], 1);
1289 string_appendn (s, "'", 1);
1291 else if (tk == tk_bool)
1293 int val = consume_count (mangled);
1294 if (val == 0)
1295 string_appendn (s, "false", 5);
1296 else if (val == 1)
1297 string_appendn (s, "true", 4);
1298 else
1299 success = 0;
1301 else if (tk == tk_real)
1303 if (**mangled == 'm')
1305 string_appendn (s, "-", 1);
1306 (*mangled)++;
1308 while (isdigit (**mangled))
1310 string_appendn (s, *mangled, 1);
1311 (*mangled)++;
1313 if (**mangled == '.') /* fraction */
1315 string_appendn (s, ".", 1);
1316 (*mangled)++;
1317 while (isdigit (**mangled))
1319 string_appendn (s, *mangled, 1);
1320 (*mangled)++;
1323 if (**mangled == 'e') /* exponent */
1325 string_appendn (s, "e", 1);
1326 (*mangled)++;
1327 while (isdigit (**mangled))
1329 string_appendn (s, *mangled, 1);
1330 (*mangled)++;
1334 else if (tk == tk_pointer)
1336 int symbol_len = consume_count (mangled);
1337 if (symbol_len == 0)
1338 return -1;
1339 if (symbol_len == 0)
1340 string_appendn (s, "0", 1);
1341 else
1343 char *p = xmalloc (symbol_len + 1), *q;
1344 strncpy (p, *mangled, symbol_len);
1345 p [symbol_len] = '\0';
1346 q = internal_cplus_demangle (work, p);
1347 string_appendn (s, "&", 1);
1348 if (q)
1350 string_append (s, q);
1351 free (q);
1353 else
1354 string_append (s, p);
1355 free (p);
1357 *mangled += symbol_len;
1360 return success;
1363 /* Demangle the template name in MANGLED. The full name of the
1364 template (e.g., S<int>) is placed in TNAME. The name without the
1365 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1366 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1367 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1368 the tmeplate is remembered in the list of back-referenceable
1369 types. */
1371 static int
1372 demangle_template (work, mangled, tname, trawname, is_type, remember)
1373 struct work_stuff *work;
1374 const char **mangled;
1375 string *tname;
1376 string *trawname;
1377 int is_type;
1378 int remember;
1380 int i;
1381 int r;
1382 int need_comma = 0;
1383 int success = 0;
1384 const char *start;
1385 string temp;
1386 int bindex;
1388 (*mangled)++;
1389 if (is_type)
1391 if (remember)
1392 bindex = register_Btype (work);
1393 start = *mangled;
1394 /* get template name */
1395 if (**mangled == 'z')
1397 int idx;
1398 (*mangled)++;
1399 (*mangled)++;
1401 idx = consume_count_with_underscores (mangled);
1402 if (idx == -1
1403 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1404 || consume_count_with_underscores (mangled) == -1)
1405 return (0);
1407 if (work->tmpl_argvec)
1409 string_append (tname, work->tmpl_argvec[idx]);
1410 if (trawname)
1411 string_append (trawname, work->tmpl_argvec[idx]);
1413 else
1415 char buf[10];
1416 sprintf(buf, "T%d", idx);
1417 string_append (tname, buf);
1418 if (trawname)
1419 string_append (trawname, buf);
1422 else
1424 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
1426 return (0);
1428 string_appendn (tname, *mangled, r);
1429 if (trawname)
1430 string_appendn (trawname, *mangled, r);
1431 *mangled += r;
1434 string_append (tname, "<");
1435 /* get size of template parameter list */
1436 if (!get_count (mangled, &r))
1438 return (0);
1440 if (!is_type)
1442 /* Create an array for saving the template argument values. */
1443 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1444 work->ntmpl_args = r;
1445 for (i = 0; i < r; i++)
1446 work->tmpl_argvec[i] = 0;
1448 for (i = 0; i < r; i++)
1450 if (need_comma)
1452 string_append (tname, ", ");
1454 /* Z for type parameters */
1455 if (**mangled == 'Z')
1457 (*mangled)++;
1458 /* temp is initialized in do_type */
1459 success = do_type (work, mangled, &temp);
1460 if (success)
1462 string_appends (tname, &temp);
1464 if (!is_type)
1466 /* Save the template argument. */
1467 int len = temp.p - temp.b;
1468 work->tmpl_argvec[i] = xmalloc (len + 1);
1469 memcpy (work->tmpl_argvec[i], temp.b, len);
1470 work->tmpl_argvec[i][len] = '\0';
1473 string_delete(&temp);
1474 if (!success)
1476 break;
1479 /* z for template parameters */
1480 else if (**mangled == 'z')
1482 int r2;
1483 (*mangled)++;
1484 success = demangle_template_template_parm (work, mangled, tname);
1486 if (success
1487 && (r2 = consume_count (mangled)) > 0 && strlen (*mangled) >= r2)
1489 string_append (tname, " ");
1490 string_appendn (tname, *mangled, r2);
1491 if (!is_type)
1493 /* Save the template argument. */
1494 int len = r2;
1495 work->tmpl_argvec[i] = xmalloc (len + 1);
1496 memcpy (work->tmpl_argvec[i], *mangled, len);
1497 work->tmpl_argvec[i][len] = '\0';
1499 *mangled += r2;
1501 if (!success)
1503 break;
1506 else
1508 string param;
1509 string* s;
1510 const char* start_of_value_parm = *mangled;
1512 /* otherwise, value parameter */
1514 /* temp is initialized in do_type */
1515 success = do_type (work, mangled, &temp);
1516 string_delete(&temp);
1517 if (!success)
1518 break;
1520 if (!is_type)
1522 s = &param;
1523 string_init (s);
1525 else
1526 s = tname;
1528 success = demangle_template_value_parm (work, mangled, s,
1529 (type_kind_t) success);
1531 if (!success)
1533 if (!is_type)
1534 string_delete (s);
1535 success = 0;
1536 break;
1539 if (!is_type)
1541 int len = s->p - s->b;
1542 work->tmpl_argvec[i] = xmalloc (len + 1);
1543 memcpy (work->tmpl_argvec[i], s->b, len);
1544 work->tmpl_argvec[i][len] = '\0';
1546 string_appends (tname, s);
1547 string_delete (s);
1550 need_comma = 1;
1553 if (tname->p[-1] == '>')
1554 string_append (tname, " ");
1555 string_append (tname, ">");
1558 if (is_type && remember)
1559 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1562 if (work -> static_type)
1564 string_append (declp, *mangled + 1);
1565 *mangled += strlen (*mangled);
1566 success = 1;
1568 else
1570 success = demangle_args (work, mangled, declp);
1574 return (success);
1577 static int
1578 arm_pt (work, mangled, n, anchor, args)
1579 struct work_stuff *work;
1580 const char *mangled;
1581 int n;
1582 const char **anchor, **args;
1584 /* ARM template? */
1585 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1587 int len;
1588 *args = *anchor + 6;
1589 len = consume_count (args);
1590 if (*args + len == mangled + n && **args == '_')
1592 ++*args;
1593 return 1;
1596 return 0;
1599 static void
1600 demangle_arm_pt (work, mangled, n, declp)
1601 struct work_stuff *work;
1602 const char **mangled;
1603 int n;
1604 string *declp;
1606 const char *p;
1607 const char *args;
1608 const char *e = *mangled + n;
1610 /* ARM template? */
1611 if (arm_pt (work, *mangled, n, &p, &args))
1613 string arg;
1614 string_init (&arg);
1615 string_appendn (declp, *mangled, p - *mangled);
1616 string_append (declp, "<");
1617 /* should do error checking here */
1618 while (args < e) {
1619 string_clear (&arg);
1620 do_type (work, &args, &arg);
1621 string_appends (declp, &arg);
1622 string_append (declp, ",");
1624 string_delete (&arg);
1625 --declp->p;
1626 string_append (declp, ">");
1628 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1629 && (*mangled)[9] == 'N'
1630 && (*mangled)[8] == (*mangled)[10]
1631 && strchr (cplus_markers, (*mangled)[8]))
1633 /* A member of the anonymous namespace. */
1634 string_append (declp, "{anonymous}");
1636 else
1638 string_appendn (declp, *mangled, n);
1640 *mangled += n;
1643 static int
1644 demangle_class_name (work, mangled, declp)
1645 struct work_stuff *work;
1646 const char **mangled;
1647 string *declp;
1649 int n;
1650 int success = 0;
1652 n = consume_count (mangled);
1653 if (strlen (*mangled) >= n)
1655 demangle_arm_pt (work, mangled, n, declp);
1656 success = 1;
1659 return (success);
1664 LOCAL FUNCTION
1666 demangle_class -- demangle a mangled class sequence
1668 SYNOPSIS
1670 static int
1671 demangle_class (struct work_stuff *work, const char **mangled,
1672 strint *declp)
1674 DESCRIPTION
1676 DECLP points to the buffer into which demangling is being done.
1678 *MANGLED points to the current token to be demangled. On input,
1679 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1680 On exit, it points to the next token after the mangled class on
1681 success, or the first unconsumed token on failure.
1683 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1684 we are demangling a constructor or destructor. In this case
1685 we prepend "class::class" or "class::~class" to DECLP.
1687 Otherwise, we prepend "class::" to the current DECLP.
1689 Reset the constructor/destructor flags once they have been
1690 "consumed". This allows demangle_class to be called later during
1691 the same demangling, to do normal class demangling.
1693 Returns 1 if demangling is successful, 0 otherwise.
1697 static int
1698 demangle_class (work, mangled, declp)
1699 struct work_stuff *work;
1700 const char **mangled;
1701 string *declp;
1703 int success = 0;
1704 int btype;
1705 string class_name;
1707 string_init (&class_name);
1708 btype = register_Btype (work);
1709 if (demangle_class_name (work, mangled, &class_name))
1711 if ((work->constructor & 1) || (work->destructor & 1))
1713 string_prepends (declp, &class_name);
1714 if (work -> destructor & 1)
1716 string_prepend (declp, "~");
1717 work -> destructor -= 1;
1719 else
1721 work -> constructor -= 1;
1724 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
1725 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
1726 string_prepend (declp, SCOPE_STRING (work));
1727 string_prepends (declp, &class_name);
1728 success = 1;
1730 string_delete (&class_name);
1731 return (success);
1736 LOCAL FUNCTION
1738 demangle_prefix -- consume the mangled name prefix and find signature
1740 SYNOPSIS
1742 static int
1743 demangle_prefix (struct work_stuff *work, const char **mangled,
1744 string *declp);
1746 DESCRIPTION
1748 Consume and demangle the prefix of the mangled name.
1750 DECLP points to the string buffer into which demangled output is
1751 placed. On entry, the buffer is empty. On exit it contains
1752 the root function name, the demangled operator name, or in some
1753 special cases either nothing or the completely demangled result.
1755 MANGLED points to the current pointer into the mangled name. As each
1756 token of the mangled name is consumed, it is updated. Upon entry
1757 the current mangled name pointer points to the first character of
1758 the mangled name. Upon exit, it should point to the first character
1759 of the signature if demangling was successful, or to the first
1760 unconsumed character if demangling of the prefix was unsuccessful.
1762 Returns 1 on success, 0 otherwise.
1765 static int
1766 demangle_prefix (work, mangled, declp)
1767 struct work_stuff *work;
1768 const char **mangled;
1769 string *declp;
1771 int success = 1;
1772 const char *scan;
1773 int i;
1775 if (strlen(*mangled) > 6
1776 && (strncmp(*mangled, "_imp__", 6) == 0
1777 || strncmp(*mangled, "__imp_", 6) == 0))
1779 /* it's a symbol imported from a PE dynamic library. Check for both
1780 new style prefix _imp__ and legacy __imp_ used by older versions
1781 of dlltool. */
1782 (*mangled) += 6;
1783 work->dllimported = 1;
1785 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1787 char *marker = strchr (cplus_markers, (*mangled)[8]);
1788 if (marker != NULL && *marker == (*mangled)[10])
1790 if ((*mangled)[9] == 'D')
1792 /* it's a GNU global destructor to be executed at program exit */
1793 (*mangled) += 11;
1794 work->destructor = 2;
1795 if (gnu_special (work, mangled, declp))
1796 return success;
1798 else if ((*mangled)[9] == 'I')
1800 /* it's a GNU global constructor to be executed at program init */
1801 (*mangled) += 11;
1802 work->constructor = 2;
1803 if (gnu_special (work, mangled, declp))
1804 return success;
1808 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1810 /* it's a ARM global destructor to be executed at program exit */
1811 (*mangled) += 7;
1812 work->destructor = 2;
1814 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1816 /* it's a ARM global constructor to be executed at program initial */
1817 (*mangled) += 7;
1818 work->constructor = 2;
1821 /* This block of code is a reduction in strength time optimization
1823 scan = mystrstr (*mangled, "__"); */
1826 scan = *mangled;
1828 do {
1829 scan = strchr (scan, '_');
1830 } while (scan != NULL && *++scan != '_');
1832 if (scan != NULL) --scan;
1835 if (scan != NULL)
1837 /* We found a sequence of two or more '_', ensure that we start at
1838 the last pair in the sequence. */
1839 i = strspn (scan, "_");
1840 if (i > 2)
1842 scan += (i - 2);
1846 if (scan == NULL)
1848 success = 0;
1850 else if (work -> static_type)
1852 if (!isdigit (scan[0]) && (scan[0] != 't'))
1854 success = 0;
1857 else if ((scan == *mangled)
1858 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1859 || (scan[2] == 'K') || (scan[2] == 'H')))
1861 /* The ARM says nothing about the mangling of local variables.
1862 But cfront mangles local variables by prepending __<nesting_level>
1863 to them. As an extension to ARM demangling we handle this case. */
1864 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1866 *mangled = scan + 2;
1867 consume_count (mangled);
1868 string_append (declp, *mangled);
1869 *mangled += strlen (*mangled);
1870 success = 1;
1872 else
1874 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1875 names like __Q2_3foo3bar for nested type names. So don't accept
1876 this style of constructor for cfront demangling. A GNU
1877 style member-template constructor starts with 'H'. */
1878 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1879 work -> constructor += 1;
1880 *mangled = scan + 2;
1883 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1885 /* Mangled name starts with "__". Skip over any leading '_' characters,
1886 then find the next "__" that separates the prefix from the signature.
1888 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1889 || (arm_special (mangled, declp) == 0))
1891 while (*scan == '_')
1893 scan++;
1895 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1897 /* No separator (I.E. "__not_mangled"), or empty signature
1898 (I.E. "__not_mangled_either__") */
1899 success = 0;
1901 else
1903 demangle_function_name (work, mangled, declp, scan);
1907 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1909 /* Cfront-style parameterized type. Handled later as a signature. */
1910 success = 1;
1912 /* ARM template? */
1913 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1915 else if (*(scan + 2) != '\0')
1917 /* Mangled name does not start with "__" but does have one somewhere
1918 in there with non empty stuff after it. Looks like a global
1919 function name. */
1920 demangle_function_name (work, mangled, declp, scan);
1922 else
1924 /* Doesn't look like a mangled name */
1925 success = 0;
1928 if (!success && (work->constructor == 2 || work->destructor == 2))
1930 string_append (declp, *mangled);
1931 *mangled += strlen (*mangled);
1932 success = 1;
1934 return (success);
1939 LOCAL FUNCTION
1941 gnu_special -- special handling of gnu mangled strings
1943 SYNOPSIS
1945 static int
1946 gnu_special (struct work_stuff *work, const char **mangled,
1947 string *declp);
1950 DESCRIPTION
1952 Process some special GNU style mangling forms that don't fit
1953 the normal pattern. For example:
1955 _$_3foo (destructor for class foo)
1956 _vt$foo (foo virtual table)
1957 _vt$foo$bar (foo::bar virtual table)
1958 __vt_foo (foo virtual table, new style with thunks)
1959 _3foo$varname (static data member)
1960 _Q22rs2tu$vw (static data member)
1961 __t6vector1Zii (constructor with template)
1962 __thunk_4__$_7ostream (virtual function thunk)
1965 static int
1966 gnu_special (work, mangled, declp)
1967 struct work_stuff *work;
1968 const char **mangled;
1969 string *declp;
1971 int n;
1972 int success = 1;
1973 const char *p;
1975 if ((*mangled)[0] == '_'
1976 && strchr (cplus_markers, (*mangled)[1]) != NULL
1977 && (*mangled)[2] == '_')
1979 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1980 (*mangled) += 3;
1981 work -> destructor += 1;
1983 else if ((*mangled)[0] == '_'
1984 && (((*mangled)[1] == '_'
1985 && (*mangled)[2] == 'v'
1986 && (*mangled)[3] == 't'
1987 && (*mangled)[4] == '_')
1988 || ((*mangled)[1] == 'v'
1989 && (*mangled)[2] == 't'
1990 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1992 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1993 and create the decl. Note that we consume the entire mangled
1994 input string, which means that demangle_signature has no work
1995 to do. */
1996 if ((*mangled)[2] == 'v')
1997 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1998 else
1999 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2000 while (**mangled != '\0')
2002 p = strpbrk (*mangled, cplus_markers);
2003 switch (**mangled)
2005 case 'Q':
2006 case 'K':
2007 success = demangle_qualified (work, mangled, declp, 0, 1);
2008 break;
2009 case 't':
2010 success = demangle_template (work, mangled, declp, 0, 1,
2012 break;
2013 default:
2014 if (isdigit(*mangled[0]))
2016 n = consume_count(mangled);
2017 /* We may be seeing a too-large size, or else a
2018 ".<digits>" indicating a static local symbol. In
2019 any case, declare victory and move on; *don't* try
2020 to use n to allocate. */
2021 if (n > strlen (*mangled))
2023 success = 1;
2024 break;
2027 else
2029 n = strcspn (*mangled, cplus_markers);
2031 string_appendn (declp, *mangled, n);
2032 (*mangled) += n;
2035 if (success && ((p == NULL) || (p == *mangled)))
2037 if (p != NULL)
2039 string_append (declp, SCOPE_STRING (work));
2040 (*mangled)++;
2043 else
2045 success = 0;
2046 break;
2049 if (success)
2050 string_append (declp, " virtual table");
2052 else if ((*mangled)[0] == '_'
2053 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2054 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2056 /* static data member, "_3foo$varname" for example */
2057 (*mangled)++;
2058 switch (**mangled)
2060 case 'Q':
2061 case 'K':
2062 success = demangle_qualified (work, mangled, declp, 0, 1);
2063 break;
2064 case 't':
2065 success = demangle_template (work, mangled, declp, 0, 1, 1);
2066 break;
2067 default:
2068 n = consume_count (mangled);
2069 string_appendn (declp, *mangled, n);
2070 (*mangled) += n;
2072 if (success && (p == *mangled))
2074 /* Consumed everything up to the cplus_marker, append the
2075 variable name. */
2076 (*mangled)++;
2077 string_append (declp, SCOPE_STRING (work));
2078 n = strlen (*mangled);
2079 string_appendn (declp, *mangled, n);
2080 (*mangled) += n;
2082 else
2084 success = 0;
2087 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2089 int delta = ((*mangled) += 8, consume_count (mangled));
2090 char *method = internal_cplus_demangle (work, ++*mangled);
2091 if (method)
2093 char buf[50];
2094 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2095 string_append (declp, buf);
2096 string_append (declp, method);
2097 free (method);
2098 n = strlen (*mangled);
2099 (*mangled) += n;
2101 else
2103 success = 0;
2106 else if (strncmp (*mangled, "__t", 3) == 0
2107 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2109 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2110 (*mangled) += 4;
2111 switch (**mangled)
2113 case 'Q':
2114 case 'K':
2115 success = demangle_qualified (work, mangled, declp, 0, 1);
2116 break;
2117 case 't':
2118 success = demangle_template (work, mangled, declp, 0, 1, 1);
2119 break;
2120 default:
2121 success = demangle_fund_type (work, mangled, declp);
2122 break;
2124 if (success && **mangled != '\0')
2125 success = 0;
2126 if (success)
2127 string_append (declp, p);
2129 else
2131 success = 0;
2133 return (success);
2138 LOCAL FUNCTION
2140 arm_special -- special handling of ARM/lucid mangled strings
2142 SYNOPSIS
2144 static int
2145 arm_special (const char **mangled,
2146 string *declp);
2149 DESCRIPTION
2151 Process some special ARM style mangling forms that don't fit
2152 the normal pattern. For example:
2154 __vtbl__3foo (foo virtual table)
2155 __vtbl__3foo__3bar (bar::foo virtual table)
2159 static int
2160 arm_special (mangled, declp)
2161 const char **mangled;
2162 string *declp;
2164 int n;
2165 int success = 1;
2166 const char *scan;
2168 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2170 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2171 and create the decl. Note that we consume the entire mangled
2172 input string, which means that demangle_signature has no work
2173 to do. */
2174 scan = *mangled + ARM_VTABLE_STRLEN;
2175 while (*scan != '\0') /* first check it can be demangled */
2177 n = consume_count (&scan);
2178 if (n==0)
2180 return (0); /* no good */
2182 scan += n;
2183 if (scan[0] == '_' && scan[1] == '_')
2185 scan += 2;
2188 (*mangled) += ARM_VTABLE_STRLEN;
2189 while (**mangled != '\0')
2191 n = consume_count (mangled);
2192 string_prependn (declp, *mangled, n);
2193 (*mangled) += n;
2194 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2196 string_prepend (declp, "::");
2197 (*mangled) += 2;
2200 string_append (declp, " virtual table");
2202 else
2204 success = 0;
2206 return (success);
2211 LOCAL FUNCTION
2213 demangle_qualified -- demangle 'Q' qualified name strings
2215 SYNOPSIS
2217 static int
2218 demangle_qualified (struct work_stuff *, const char *mangled,
2219 string *result, int isfuncname, int append);
2221 DESCRIPTION
2223 Demangle a qualified name, such as "Q25Outer5Inner" which is
2224 the mangled form of "Outer::Inner". The demangled output is
2225 prepended or appended to the result string according to the
2226 state of the append flag.
2228 If isfuncname is nonzero, then the qualified name we are building
2229 is going to be used as a member function name, so if it is a
2230 constructor or destructor function, append an appropriate
2231 constructor or destructor name. I.E. for the above example,
2232 the result for use as a constructor is "Outer::Inner::Inner"
2233 and the result for use as a destructor is "Outer::Inner::~Inner".
2235 BUGS
2237 Numeric conversion is ASCII dependent (FIXME).
2241 static int
2242 demangle_qualified (work, mangled, result, isfuncname, append)
2243 struct work_stuff *work;
2244 const char **mangled;
2245 string *result;
2246 int isfuncname;
2247 int append;
2249 int qualifiers = 0;
2250 int success = 1;
2251 const char *p;
2252 char num[2];
2253 string temp;
2254 string last_name;
2255 int bindex = register_Btype (work);
2257 /* We only make use of ISFUNCNAME if the entity is a constructor or
2258 destructor. */
2259 isfuncname = (isfuncname
2260 && ((work->constructor & 1) || (work->destructor & 1)));
2262 string_init (&temp);
2263 string_init (&last_name);
2265 if ((*mangled)[0] == 'K')
2267 /* Squangling qualified name reuse */
2268 int idx;
2269 (*mangled)++;
2270 idx = consume_count_with_underscores (mangled);
2271 if (idx == -1 || idx > work -> numk)
2272 success = 0;
2273 else
2274 string_append (&temp, work -> ktypevec[idx]);
2276 else
2277 switch ((*mangled)[1])
2279 case '_':
2280 /* GNU mangled name with more than 9 classes. The count is preceded
2281 by an underscore (to distinguish it from the <= 9 case) and followed
2282 by an underscore. */
2283 p = *mangled + 2;
2284 qualifiers = atoi (p);
2285 if (!isdigit (*p) || *p == '0')
2286 success = 0;
2288 /* Skip the digits. */
2289 while (isdigit (*p))
2290 ++p;
2292 if (*p != '_')
2293 success = 0;
2295 *mangled = p + 1;
2296 break;
2298 case '1':
2299 case '2':
2300 case '3':
2301 case '4':
2302 case '5':
2303 case '6':
2304 case '7':
2305 case '8':
2306 case '9':
2307 /* The count is in a single digit. */
2308 num[0] = (*mangled)[1];
2309 num[1] = '\0';
2310 qualifiers = atoi (num);
2312 /* If there is an underscore after the digit, skip it. This is
2313 said to be for ARM-qualified names, but the ARM makes no
2314 mention of such an underscore. Perhaps cfront uses one. */
2315 if ((*mangled)[2] == '_')
2317 (*mangled)++;
2319 (*mangled) += 2;
2320 break;
2322 case '0':
2323 default:
2324 success = 0;
2327 if (!success)
2328 return success;
2330 /* Pick off the names and collect them in the temp buffer in the order
2331 in which they are found, separated by '::'. */
2333 while (qualifiers-- > 0)
2335 int remember_K = 1;
2336 string_clear (&last_name);
2338 if (*mangled[0] == '_')
2339 (*mangled)++;
2341 if (*mangled[0] == 't')
2343 /* Here we always append to TEMP since we will want to use
2344 the template name without the template parameters as a
2345 constructor or destructor name. The appropriate
2346 (parameter-less) value is returned by demangle_template
2347 in LAST_NAME. We do not remember the template type here,
2348 in order to match the G++ mangling algorithm. */
2349 success = demangle_template(work, mangled, &temp,
2350 &last_name, 1, 0);
2351 if (!success)
2352 break;
2354 else if (*mangled[0] == 'K')
2356 int idx;
2357 (*mangled)++;
2358 idx = consume_count_with_underscores (mangled);
2359 if (idx == -1 || idx > work->numk)
2360 success = 0;
2361 else
2362 string_append (&temp, work->ktypevec[idx]);
2363 remember_K = 0;
2365 if (!success) break;
2367 else
2369 success = do_type (work, mangled, &last_name);
2370 if (!success)
2371 break;
2372 string_appends (&temp, &last_name);
2375 if (remember_K)
2376 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2378 if (qualifiers > 0)
2379 string_append (&temp, SCOPE_STRING (work));
2382 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2384 /* If we are using the result as a function name, we need to append
2385 the appropriate '::' separated constructor or destructor name.
2386 We do this here because this is the most convenient place, where
2387 we already have a pointer to the name and the length of the name. */
2389 if (isfuncname)
2391 string_append (&temp, SCOPE_STRING (work));
2392 if (work -> destructor & 1)
2393 string_append (&temp, "~");
2394 string_appends (&temp, &last_name);
2397 /* Now either prepend the temp buffer to the result, or append it,
2398 depending upon the state of the append flag. */
2400 if (append)
2401 string_appends (result, &temp);
2402 else
2404 if (!STRING_EMPTY (result))
2405 string_append (&temp, SCOPE_STRING (work));
2406 string_prepends (result, &temp);
2409 string_delete (&last_name);
2410 string_delete (&temp);
2411 return (success);
2416 LOCAL FUNCTION
2418 get_count -- convert an ascii count to integer, consuming tokens
2420 SYNOPSIS
2422 static int
2423 get_count (const char **type, int *count)
2425 DESCRIPTION
2427 Return 0 if no conversion is performed, 1 if a string is converted.
2430 static int
2431 get_count (type, count)
2432 const char **type;
2433 int *count;
2435 const char *p;
2436 int n;
2438 if (!isdigit (**type))
2440 return (0);
2442 else
2444 *count = **type - '0';
2445 (*type)++;
2446 if (isdigit (**type))
2448 p = *type;
2449 n = *count;
2452 n *= 10;
2453 n += *p - '0';
2454 p++;
2456 while (isdigit (*p));
2457 if (*p == '_')
2459 *type = p + 1;
2460 *count = n;
2464 return (1);
2467 /* RESULT will be initialised here; it will be freed on failure. The
2468 value returned is really a type_kind_t. */
2470 static int
2471 do_type (work, mangled, result)
2472 struct work_stuff *work;
2473 const char **mangled;
2474 string *result;
2476 int n;
2477 int done;
2478 int success;
2479 string decl;
2480 const char *remembered_type;
2481 int constp;
2482 int volatilep;
2483 string btype;
2484 type_kind_t tk = tk_none;
2486 string_init (&btype);
2487 string_init (&decl);
2488 string_init (result);
2490 done = 0;
2491 success = 1;
2492 while (success && !done)
2494 int member;
2495 switch (**mangled)
2498 /* A pointer type */
2499 case 'P':
2500 case 'p':
2501 (*mangled)++;
2502 string_prepend (&decl, "*");
2503 if (tk == tk_none)
2504 tk = tk_pointer;
2505 break;
2507 /* A reference type */
2508 case 'R':
2509 (*mangled)++;
2510 string_prepend (&decl, "&");
2511 if (tk == tk_none)
2512 tk = tk_pointer;
2513 break;
2515 /* An array */
2516 case 'A':
2518 ++(*mangled);
2519 if (!STRING_EMPTY (&decl)
2520 && (decl.b[0] == '*' || decl.b[0] == '&'))
2522 string_prepend (&decl, "(");
2523 string_append (&decl, ")");
2525 string_append (&decl, "[");
2526 if (**mangled != '_')
2527 success = demangle_template_value_parm (work, mangled, &decl,
2528 tk_integral);
2529 if (**mangled == '_')
2530 ++(*mangled);
2531 string_append (&decl, "]");
2532 break;
2535 /* A back reference to a previously seen type */
2536 case 'T':
2537 (*mangled)++;
2538 if (!get_count (mangled, &n) || n >= work -> ntypes)
2540 success = 0;
2542 else
2544 remembered_type = work -> typevec[n];
2545 mangled = &remembered_type;
2547 break;
2549 /* A function */
2550 case 'F':
2551 (*mangled)++;
2552 if (!STRING_EMPTY (&decl)
2553 && (decl.b[0] == '*' || decl.b[0] == '&'))
2555 string_prepend (&decl, "(");
2556 string_append (&decl, ")");
2558 /* After picking off the function args, we expect to either find the
2559 function return type (preceded by an '_') or the end of the
2560 string. */
2561 if (!demangle_nested_args (work, mangled, &decl)
2562 || (**mangled != '_' && **mangled != '\0'))
2564 success = 0;
2565 break;
2567 if (success && (**mangled == '_'))
2568 (*mangled)++;
2569 break;
2571 case 'M':
2572 case 'O':
2574 constp = 0;
2575 volatilep = 0;
2577 member = **mangled == 'M';
2578 (*mangled)++;
2579 if (!isdigit (**mangled) && **mangled != 't')
2581 success = 0;
2582 break;
2585 string_append (&decl, ")");
2586 string_prepend (&decl, SCOPE_STRING (work));
2587 if (isdigit (**mangled))
2589 n = consume_count (mangled);
2590 if (strlen (*mangled) < n)
2592 success = 0;
2593 break;
2595 string_prependn (&decl, *mangled, n);
2596 *mangled += n;
2598 else
2600 string temp;
2601 string_init (&temp);
2602 success = demangle_template (work, mangled, &temp,
2603 NULL, 1, 1);
2604 if (success)
2606 string_prependn (&decl, temp.b, temp.p - temp.b);
2607 string_clear (&temp);
2609 else
2610 break;
2612 string_prepend (&decl, "(");
2613 if (member)
2615 if (**mangled == 'C')
2617 (*mangled)++;
2618 constp = 1;
2620 if (**mangled == 'V')
2622 (*mangled)++;
2623 volatilep = 1;
2625 if (*(*mangled)++ != 'F')
2627 success = 0;
2628 break;
2631 if ((member && !demangle_nested_args (work, mangled, &decl))
2632 || **mangled != '_')
2634 success = 0;
2635 break;
2637 (*mangled)++;
2638 if (! PRINT_ANSI_QUALIFIERS)
2640 break;
2642 if (constp)
2644 APPEND_BLANK (&decl);
2645 string_append (&decl, "const");
2647 if (volatilep)
2649 APPEND_BLANK (&decl);
2650 string_append (&decl, "volatile");
2652 break;
2654 case 'G':
2655 (*mangled)++;
2656 break;
2658 case 'C':
2659 case 'V':
2661 if ((*mangled)[1] == 'P')
2664 if (PRINT_ANSI_QUALIFIERS)
2666 if (!STRING_EMPTY (&decl))
2668 string_prepend (&decl, " ");
2670 string_prepend (&decl,
2671 (**mangled) == 'C' ? "const" : "volatile");
2673 (*mangled)++;
2674 break;
2679 /* fall through */
2680 default:
2681 done = 1;
2682 break;
2686 if (success) switch (**mangled)
2688 /* A qualified name, such as "Outer::Inner". */
2689 case 'Q':
2690 case 'K':
2692 success = demangle_qualified (work, mangled, result, 0, 1);
2693 break;
2696 /* A back reference to a previously seen squangled type */
2697 case 'B':
2698 (*mangled)++;
2699 if (!get_count (mangled, &n) || n >= work -> numb)
2700 success = 0;
2701 else
2702 string_append (result, work->btypevec[n]);
2703 break;
2705 case 'X':
2706 case 'Y':
2707 /* A template parm. We substitute the corresponding argument. */
2709 int idx;
2711 (*mangled)++;
2712 idx = consume_count_with_underscores (mangled);
2714 if (idx == -1
2715 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2716 || consume_count_with_underscores (mangled) == -1)
2718 success = 0;
2719 break;
2722 if (work->tmpl_argvec)
2723 string_append (result, work->tmpl_argvec[idx]);
2724 else
2726 char buf[10];
2727 sprintf(buf, "T%d", idx);
2728 string_append (result, buf);
2731 success = 1;
2733 break;
2735 default:
2736 success = demangle_fund_type (work, mangled, result);
2737 if (tk == tk_none)
2738 tk = (type_kind_t) success;
2739 break;
2742 if (success)
2744 if (!STRING_EMPTY (&decl))
2746 string_append (result, " ");
2747 string_appends (result, &decl);
2750 else
2751 string_delete (result);
2752 string_delete (&decl);
2754 if (success)
2755 /* Assume an integral type, if we're not sure. */
2756 return (int) ((tk == tk_none) ? tk_integral : tk);
2757 else
2758 return 0;
2761 /* Given a pointer to a type string that represents a fundamental type
2762 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2763 string in which the demangled output is being built in RESULT, and
2764 the WORK structure, decode the types and add them to the result.
2766 For example:
2768 "Ci" => "const int"
2769 "Sl" => "signed long"
2770 "CUs" => "const unsigned short"
2772 The value returned is really a type_kind_t. */
2774 static int
2775 demangle_fund_type (work, mangled, result)
2776 struct work_stuff *work;
2777 const char **mangled;
2778 string *result;
2780 int done = 0;
2781 int success = 1;
2782 string btype;
2783 type_kind_t tk = tk_integral;
2785 string_init (&btype);
2787 /* First pick off any type qualifiers. There can be more than one. */
2789 while (!done)
2791 switch (**mangled)
2793 case 'C':
2794 (*mangled)++;
2795 if (PRINT_ANSI_QUALIFIERS)
2797 APPEND_BLANK (result);
2798 string_append (result, "const");
2800 break;
2801 case 'U':
2802 (*mangled)++;
2803 APPEND_BLANK (result);
2804 string_append (result, "unsigned");
2805 break;
2806 case 'S': /* signed char only */
2807 (*mangled)++;
2808 APPEND_BLANK (result);
2809 string_append (result, "signed");
2810 break;
2811 case 'V':
2812 (*mangled)++;
2813 if (PRINT_ANSI_QUALIFIERS)
2815 APPEND_BLANK (result);
2816 string_append (result, "volatile");
2818 break;
2819 case 'J':
2820 (*mangled)++;
2821 APPEND_BLANK (result);
2822 string_append (result, "__complex");
2823 break;
2824 default:
2825 done = 1;
2826 break;
2830 /* Now pick off the fundamental type. There can be only one. */
2832 switch (**mangled)
2834 case '\0':
2835 case '_':
2836 break;
2837 case 'v':
2838 (*mangled)++;
2839 APPEND_BLANK (result);
2840 string_append (result, "void");
2841 break;
2842 case 'x':
2843 (*mangled)++;
2844 APPEND_BLANK (result);
2845 string_append (result, "long long");
2846 break;
2847 case 'l':
2848 (*mangled)++;
2849 APPEND_BLANK (result);
2850 string_append (result, "long");
2851 break;
2852 case 'i':
2853 (*mangled)++;
2854 APPEND_BLANK (result);
2855 string_append (result, "int");
2856 break;
2857 case 's':
2858 (*mangled)++;
2859 APPEND_BLANK (result);
2860 string_append (result, "short");
2861 break;
2862 case 'b':
2863 (*mangled)++;
2864 APPEND_BLANK (result);
2865 string_append (result, "bool");
2866 tk = tk_bool;
2867 break;
2868 case 'c':
2869 (*mangled)++;
2870 APPEND_BLANK (result);
2871 string_append (result, "char");
2872 tk = tk_char;
2873 break;
2874 case 'w':
2875 (*mangled)++;
2876 APPEND_BLANK (result);
2877 string_append (result, "wchar_t");
2878 tk = tk_char;
2879 break;
2880 case 'r':
2881 (*mangled)++;
2882 APPEND_BLANK (result);
2883 string_append (result, "long double");
2884 tk = tk_real;
2885 break;
2886 case 'd':
2887 (*mangled)++;
2888 APPEND_BLANK (result);
2889 string_append (result, "double");
2890 tk = tk_real;
2891 break;
2892 case 'f':
2893 (*mangled)++;
2894 APPEND_BLANK (result);
2895 string_append (result, "float");
2896 tk = tk_real;
2897 break;
2898 case 'G':
2899 (*mangled)++;
2900 if (!isdigit (**mangled))
2902 success = 0;
2903 break;
2905 /* fall through */
2906 /* An explicit type, such as "6mytype" or "7integer" */
2907 case '0':
2908 case '1':
2909 case '2':
2910 case '3':
2911 case '4':
2912 case '5':
2913 case '6':
2914 case '7':
2915 case '8':
2916 case '9':
2918 int bindex = register_Btype (work);
2919 string btype;
2920 string_init (&btype);
2921 if (demangle_class_name (work, mangled, &btype)) {
2922 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
2923 APPEND_BLANK (result);
2924 string_appends (result, &btype);
2926 else
2927 success = 0;
2928 string_delete (&btype);
2929 break;
2931 case 't':
2933 success = demangle_template (work, mangled, &btype, 0, 1, 1);
2934 string_appends (result, &btype);
2935 break;
2937 default:
2938 success = 0;
2939 break;
2942 return success ? ((int) tk) : 0;
2945 /* Demangle the next argument, given by MANGLED into RESULT, which
2946 *should be an uninitialized* string. It will be initialized here,
2947 and free'd should anything go wrong. */
2949 static int
2950 do_arg (work, mangled, result)
2951 struct work_stuff *work;
2952 const char **mangled;
2953 string *result;
2955 /* Remember where we started so that we can record the type, for
2956 non-squangling type remembering. */
2957 const char *start = *mangled;
2959 string_init (result);
2961 if (work->nrepeats > 0)
2963 --work->nrepeats;
2965 if (work->previous_argument == 0)
2966 return 0;
2968 /* We want to reissue the previous type in this argument list. */
2969 string_appends (result, work->previous_argument);
2970 return 1;
2973 if (**mangled == 'n')
2975 /* A squangling-style repeat. */
2976 (*mangled)++;
2977 work->nrepeats = consume_count(mangled);
2979 if (work->nrepeats == 0)
2980 /* This was not a repeat count after all. */
2981 return 0;
2983 if (work->nrepeats > 9)
2985 if (**mangled != '_')
2986 /* The repeat count should be followed by an '_' in this
2987 case. */
2988 return 0;
2989 else
2990 (*mangled)++;
2993 /* Now, the repeat is all set up. */
2994 return do_arg (work, mangled, result);
2997 /* Save the result in WORK->previous_argument so that we can find it
2998 if it's repeated. Note that saving START is not good enough: we
2999 do not want to add additional types to the back-referenceable
3000 type vector when processing a repeated type. */
3001 if (work->previous_argument)
3002 string_clear (work->previous_argument);
3003 else
3005 work->previous_argument = (string*) xmalloc (sizeof (string));
3006 string_init (work->previous_argument);
3009 if (!do_type (work, mangled, work->previous_argument))
3010 return 0;
3012 string_appends (result, work->previous_argument);
3014 remember_type (work, start, *mangled - start);
3015 return 1;
3018 static void
3019 remember_type (work, start, len)
3020 struct work_stuff *work;
3021 const char *start;
3022 int len;
3024 char *tem;
3026 if (work->forgetting_types)
3027 return;
3029 if (work -> ntypes >= work -> typevec_size)
3031 if (work -> typevec_size == 0)
3033 work -> typevec_size = 3;
3034 work -> typevec
3035 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3037 else
3039 work -> typevec_size *= 2;
3040 work -> typevec
3041 = (char **) xrealloc ((char *)work -> typevec,
3042 sizeof (char *) * work -> typevec_size);
3045 tem = xmalloc (len + 1);
3046 memcpy (tem, start, len);
3047 tem[len] = '\0';
3048 work -> typevec[work -> ntypes++] = tem;
3052 /* Remember a K type class qualifier. */
3053 static void
3054 remember_Ktype (work, start, len)
3055 struct work_stuff *work;
3056 const char *start;
3057 int len;
3059 char *tem;
3061 if (work -> numk >= work -> ksize)
3063 if (work -> ksize == 0)
3065 work -> ksize = 5;
3066 work -> ktypevec
3067 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3069 else
3071 work -> ksize *= 2;
3072 work -> ktypevec
3073 = (char **) xrealloc ((char *)work -> ktypevec,
3074 sizeof (char *) * work -> ksize);
3077 tem = xmalloc (len + 1);
3078 memcpy (tem, start, len);
3079 tem[len] = '\0';
3080 work -> ktypevec[work -> numk++] = tem;
3083 /* Register a B code, and get an index for it. B codes are registered
3084 as they are seen, rather than as they are completed, so map<temp<char> >
3085 registers map<temp<char> > as B0, and temp<char> as B1 */
3087 static int
3088 register_Btype (work)
3089 struct work_stuff *work;
3091 int ret;
3093 if (work -> numb >= work -> bsize)
3095 if (work -> bsize == 0)
3097 work -> bsize = 5;
3098 work -> btypevec
3099 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3101 else
3103 work -> bsize *= 2;
3104 work -> btypevec
3105 = (char **) xrealloc ((char *)work -> btypevec,
3106 sizeof (char *) * work -> bsize);
3109 ret = work -> numb++;
3110 work -> btypevec[ret] = NULL;
3111 return(ret);
3114 /* Store a value into a previously registered B code type. */
3116 static void
3117 remember_Btype (work, start, len, index)
3118 struct work_stuff *work;
3119 const char *start;
3120 int len, index;
3122 char *tem;
3124 tem = xmalloc (len + 1);
3125 memcpy (tem, start, len);
3126 tem[len] = '\0';
3127 work -> btypevec[index] = tem;
3130 /* Lose all the info related to B and K type codes. */
3131 static void
3132 forget_B_and_K_types (work)
3133 struct work_stuff *work;
3135 int i;
3137 while (work -> numk > 0)
3139 i = --(work -> numk);
3140 if (work -> ktypevec[i] != NULL)
3142 free (work -> ktypevec[i]);
3143 work -> ktypevec[i] = NULL;
3147 while (work -> numb > 0)
3149 i = --(work -> numb);
3150 if (work -> btypevec[i] != NULL)
3152 free (work -> btypevec[i]);
3153 work -> btypevec[i] = NULL;
3157 /* Forget the remembered types, but not the type vector itself. */
3159 static void
3160 forget_types (work)
3161 struct work_stuff *work;
3163 int i;
3165 while (work -> ntypes > 0)
3167 i = --(work -> ntypes);
3168 if (work -> typevec[i] != NULL)
3170 free (work -> typevec[i]);
3171 work -> typevec[i] = NULL;
3176 /* Process the argument list part of the signature, after any class spec
3177 has been consumed, as well as the first 'F' character (if any). For
3178 example:
3180 "__als__3fooRT0" => process "RT0"
3181 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3183 DECLP must be already initialised, usually non-empty. It won't be freed
3184 on failure.
3186 Note that g++ differs significantly from ARM and lucid style mangling
3187 with regards to references to previously seen types. For example, given
3188 the source fragment:
3190 class foo {
3191 public:
3192 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3195 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3196 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3198 g++ produces the names:
3200 __3fooiRT0iT2iT2
3201 foo__FiR3fooiT1iT1
3203 while lcc (and presumably other ARM style compilers as well) produces:
3205 foo__FiR3fooT1T2T1T2
3206 __ct__3fooFiR3fooT1T2T1T2
3208 Note that g++ bases its type numbers starting at zero and counts all
3209 previously seen types, while lucid/ARM bases its type numbers starting
3210 at one and only considers types after it has seen the 'F' character
3211 indicating the start of the function args. For lucid/ARM style, we
3212 account for this difference by discarding any previously seen types when
3213 we see the 'F' character, and subtracting one from the type number
3214 reference.
3218 static int
3219 demangle_args (work, mangled, declp)
3220 struct work_stuff *work;
3221 const char **mangled;
3222 string *declp;
3224 string arg;
3225 int need_comma = 0;
3226 int r;
3227 int t;
3228 const char *tem;
3229 char temptype;
3231 if (PRINT_ARG_TYPES)
3233 string_append (declp, "(");
3234 if (**mangled == '\0')
3236 string_append (declp, "void");
3240 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3241 || work->nrepeats > 0)
3243 if ((**mangled == 'N') || (**mangled == 'T'))
3245 temptype = *(*mangled)++;
3247 if (temptype == 'N')
3249 if (!get_count (mangled, &r))
3251 return (0);
3254 else
3256 r = 1;
3258 if (ARM_DEMANGLING && work -> ntypes >= 10)
3260 /* If we have 10 or more types we might have more than a 1 digit
3261 index so we'll have to consume the whole count here. This
3262 will lose if the next thing is a type name preceded by a
3263 count but it's impossible to demangle that case properly
3264 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3265 Pc, ...)" or "(..., type12, char *, ...)" */
3266 if ((t = consume_count(mangled)) == 0)
3268 return (0);
3271 else
3273 if (!get_count (mangled, &t))
3275 return (0);
3278 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3280 t--;
3282 /* Validate the type index. Protect against illegal indices from
3283 malformed type strings. */
3284 if ((t < 0) || (t >= work -> ntypes))
3286 return (0);
3288 while (work->nrepeats > 0 || --r >= 0)
3290 tem = work -> typevec[t];
3291 if (need_comma && PRINT_ARG_TYPES)
3293 string_append (declp, ", ");
3295 if (!do_arg (work, &tem, &arg))
3297 return (0);
3299 if (PRINT_ARG_TYPES)
3301 string_appends (declp, &arg);
3303 string_delete (&arg);
3304 need_comma = 1;
3307 else
3309 if (need_comma && PRINT_ARG_TYPES)
3310 string_append (declp, ", ");
3311 if (!do_arg (work, mangled, &arg))
3312 return (0);
3313 if (PRINT_ARG_TYPES)
3314 string_appends (declp, &arg);
3315 string_delete (&arg);
3316 need_comma = 1;
3320 if (**mangled == 'e')
3322 (*mangled)++;
3323 if (PRINT_ARG_TYPES)
3325 if (need_comma)
3327 string_append (declp, ",");
3329 string_append (declp, "...");
3333 if (PRINT_ARG_TYPES)
3335 string_append (declp, ")");
3337 return (1);
3340 /* Like demangle_args, but for demangling the argument lists of function
3341 and method pointers or references, not top-level declarations. */
3343 static int
3344 demangle_nested_args (work, mangled, declp)
3345 struct work_stuff *work;
3346 const char **mangled;
3347 string *declp;
3349 string* saved_previous_argument;
3350 int result;
3351 int saved_nrepeats;
3353 /* The G++ name-mangling algorithm does not remember types on nested
3354 argument lists, unless -fsquangling is used, and in that case the
3355 type vector updated by remember_type is not used. So, we turn
3356 off remembering of types here. */
3357 ++work->forgetting_types;
3359 /* For the repeat codes used with -fsquangling, we must keep track of
3360 the last argument. */
3361 saved_previous_argument = work->previous_argument;
3362 saved_nrepeats = work->nrepeats;
3363 work->previous_argument = 0;
3364 work->nrepeats = 0;
3366 /* Actually demangle the arguments. */
3367 result = demangle_args (work, mangled, declp);
3369 /* Restore the previous_argument field. */
3370 if (work->previous_argument)
3371 string_delete (work->previous_argument);
3372 work->previous_argument = saved_previous_argument;
3373 work->nrepeats = saved_nrepeats;
3375 return result;
3378 static void
3379 demangle_function_name (work, mangled, declp, scan)
3380 struct work_stuff *work;
3381 const char **mangled;
3382 string *declp;
3383 const char *scan;
3385 size_t i;
3386 string type;
3387 const char *tem;
3389 string_appendn (declp, (*mangled), scan - (*mangled));
3390 string_need (declp, 1);
3391 *(declp -> p) = '\0';
3393 /* Consume the function name, including the "__" separating the name
3394 from the signature. We are guaranteed that SCAN points to the
3395 separator. */
3397 (*mangled) = scan + 2;
3399 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3402 /* See if we have an ARM style constructor or destructor operator.
3403 If so, then just record it, clear the decl, and return.
3404 We can't build the actual constructor/destructor decl until later,
3405 when we recover the class name from the signature. */
3407 if (strcmp (declp -> b, "__ct") == 0)
3409 work -> constructor += 1;
3410 string_clear (declp);
3411 return;
3413 else if (strcmp (declp -> b, "__dt") == 0)
3415 work -> destructor += 1;
3416 string_clear (declp);
3417 return;
3421 if (declp->p - declp->b >= 3
3422 && declp->b[0] == 'o'
3423 && declp->b[1] == 'p'
3424 && strchr (cplus_markers, declp->b[2]) != NULL)
3426 /* see if it's an assignment expression */
3427 if (declp->p - declp->b >= 10 /* op$assign_ */
3428 && memcmp (declp->b + 3, "assign_", 7) == 0)
3430 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3432 int len = declp->p - declp->b - 10;
3433 if (strlen (optable[i].in) == len
3434 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3436 string_clear (declp);
3437 string_append (declp, "operator");
3438 string_append (declp, optable[i].out);
3439 string_append (declp, "=");
3440 break;
3444 else
3446 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3448 int len = declp->p - declp->b - 3;
3449 if (strlen (optable[i].in) == len
3450 && memcmp (optable[i].in, declp->b + 3, len) == 0)
3452 string_clear (declp);
3453 string_append (declp, "operator");
3454 string_append (declp, optable[i].out);
3455 break;
3460 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3461 && strchr (cplus_markers, declp->b[4]) != NULL)
3463 /* type conversion operator */
3464 tem = declp->b + 5;
3465 if (do_type (work, &tem, &type))
3467 string_clear (declp);
3468 string_append (declp, "operator ");
3469 string_appends (declp, &type);
3470 string_delete (&type);
3473 else if (declp->b[0] == '_' && declp->b[1] == '_'
3474 && declp->b[2] == 'o' && declp->b[3] == 'p')
3476 /* ANSI. */
3477 /* type conversion operator. */
3478 tem = declp->b + 4;
3479 if (do_type (work, &tem, &type))
3481 string_clear (declp);
3482 string_append (declp, "operator ");
3483 string_appends (declp, &type);
3484 string_delete (&type);
3487 else if (declp->b[0] == '_' && declp->b[1] == '_'
3488 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3489 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3491 if (declp->b[4] == '\0')
3493 /* Operator. */
3494 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3496 if (strlen (optable[i].in) == 2
3497 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3499 string_clear (declp);
3500 string_append (declp, "operator");
3501 string_append (declp, optable[i].out);
3502 break;
3506 else
3508 if (declp->b[2] == 'a' && declp->b[5] == '\0')
3510 /* Assignment. */
3511 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3513 if (strlen (optable[i].in) == 3
3514 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3516 string_clear (declp);
3517 string_append (declp, "operator");
3518 string_append (declp, optable[i].out);
3519 break;
3527 /* a mini string-handling package */
3529 static void
3530 string_need (s, n)
3531 string *s;
3532 int n;
3534 int tem;
3536 if (s->b == NULL)
3538 if (n < 32)
3540 n = 32;
3542 s->p = s->b = xmalloc (n);
3543 s->e = s->b + n;
3545 else if (s->e - s->p < n)
3547 tem = s->p - s->b;
3548 n += tem;
3549 n *= 2;
3550 s->b = xrealloc (s->b, n);
3551 s->p = s->b + tem;
3552 s->e = s->b + n;
3556 static void
3557 string_delete (s)
3558 string *s;
3560 if (s->b != NULL)
3562 free (s->b);
3563 s->b = s->e = s->p = NULL;
3567 static void
3568 string_init (s)
3569 string *s;
3571 s->b = s->p = s->e = NULL;
3574 static void
3575 string_clear (s)
3576 string *s;
3578 s->p = s->b;
3581 #if 0
3583 static int
3584 string_empty (s)
3585 string *s;
3587 return (s->b == s->p);
3590 #endif
3592 static void
3593 string_append (p, s)
3594 string *p;
3595 const char *s;
3597 int n;
3598 if (s == NULL || *s == '\0')
3599 return;
3600 n = strlen (s);
3601 string_need (p, n);
3602 memcpy (p->p, s, n);
3603 p->p += n;
3606 static void
3607 string_appends (p, s)
3608 string *p, *s;
3610 int n;
3612 if (s->b != s->p)
3614 n = s->p - s->b;
3615 string_need (p, n);
3616 memcpy (p->p, s->b, n);
3617 p->p += n;
3621 static void
3622 string_appendn (p, s, n)
3623 string *p;
3624 const char *s;
3625 int n;
3627 if (n != 0)
3629 string_need (p, n);
3630 memcpy (p->p, s, n);
3631 p->p += n;
3635 static void
3636 string_prepend (p, s)
3637 string *p;
3638 const char *s;
3640 if (s != NULL && *s != '\0')
3642 string_prependn (p, s, strlen (s));
3646 static void
3647 string_prepends (p, s)
3648 string *p, *s;
3650 if (s->b != s->p)
3652 string_prependn (p, s->b, s->p - s->b);
3656 static void
3657 string_prependn (p, s, n)
3658 string *p;
3659 const char *s;
3660 int n;
3662 char *q;
3664 if (n != 0)
3666 string_need (p, n);
3667 for (q = p->p - 1; q >= p->b; q--)
3669 q[n] = q[0];
3671 memcpy (p->b, s, n);
3672 p->p += n;
3676 /* To generate a standalone demangler program for testing purposes,
3677 just compile and link this file with -DMAIN and libiberty.a. When
3678 run, it demangles each command line arg, or each stdin string, and
3679 prints the result on stdout. */
3681 #ifdef MAIN
3683 #include "getopt.h"
3685 static char *program_name;
3686 static char *program_version = VERSION;
3687 static int flags = DMGL_PARAMS | DMGL_ANSI;
3689 static void demangle_it PARAMS ((char *));
3690 static void usage PARAMS ((FILE *, int));
3691 static void fatal PARAMS ((char *));
3693 static void
3694 demangle_it (mangled_name)
3695 char *mangled_name;
3697 char *result;
3699 result = cplus_demangle (mangled_name, flags);
3700 if (result == NULL)
3702 printf ("%s\n", mangled_name);
3704 else
3706 printf ("%s\n", result);
3707 free (result);
3711 static void
3712 usage (stream, status)
3713 FILE *stream;
3714 int status;
3716 fprintf (stream, "\
3717 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3718 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3719 [--help] [--version] [arg...]\n",
3720 program_name);
3721 exit (status);
3724 #define MBUF_SIZE 32767
3725 char mbuffer[MBUF_SIZE];
3727 /* Defined in the automatically-generated underscore.c. */
3728 extern int prepends_underscore;
3730 int strip_underscore = 0;
3732 static struct option long_options[] = {
3733 {"strip-underscores", no_argument, 0, '_'},
3734 {"format", required_argument, 0, 's'},
3735 {"help", no_argument, 0, 'h'},
3736 {"no-strip-underscores", no_argument, 0, 'n'},
3737 {"version", no_argument, 0, 'v'},
3738 {0, no_argument, 0, 0}
3741 /* More 'friendly' abort that prints the line and file.
3742 config.h can #define abort fancy_abort if you like that sort of thing. */
3744 void
3745 fancy_abort ()
3747 fatal ("Internal gcc abort.");
3751 main (argc, argv)
3752 int argc;
3753 char **argv;
3755 char *result;
3756 int c;
3758 program_name = argv[0];
3760 strip_underscore = prepends_underscore;
3762 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3764 switch (c)
3766 case '?':
3767 usage (stderr, 1);
3768 break;
3769 case 'h':
3770 usage (stdout, 0);
3771 case 'n':
3772 strip_underscore = 0;
3773 break;
3774 case 'v':
3775 printf ("GNU %s version %s\n", program_name, program_version);
3776 exit (0);
3777 case '_':
3778 strip_underscore = 1;
3779 break;
3780 case 's':
3781 if (strcmp (optarg, "gnu") == 0)
3783 current_demangling_style = gnu_demangling;
3785 else if (strcmp (optarg, "lucid") == 0)
3787 current_demangling_style = lucid_demangling;
3789 else if (strcmp (optarg, "arm") == 0)
3791 current_demangling_style = arm_demangling;
3793 else
3795 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3796 program_name, optarg);
3797 exit (1);
3799 break;
3803 if (optind < argc)
3805 for ( ; optind < argc; optind++)
3807 demangle_it (argv[optind]);
3810 else
3812 for (;;)
3814 int i = 0;
3815 c = getchar ();
3816 /* Try to read a label. */
3817 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3819 if (i >= MBUF_SIZE-1)
3820 break;
3821 mbuffer[i++] = c;
3822 c = getchar ();
3824 if (i > 0)
3826 int skip_first = 0;
3828 if (mbuffer[0] == '.')
3829 ++skip_first;
3830 if (strip_underscore && mbuffer[skip_first] == '_')
3831 ++skip_first;
3833 if (skip_first > i)
3834 skip_first = i;
3836 mbuffer[i] = 0;
3838 result = cplus_demangle (mbuffer + skip_first, flags);
3839 if (result)
3841 if (mbuffer[0] == '.')
3842 putc ('.', stdout);
3843 fputs (result, stdout);
3844 free (result);
3846 else
3847 fputs (mbuffer, stdout);
3849 fflush (stdout);
3851 if (c == EOF)
3852 break;
3853 putchar (c);
3857 exit (0);
3860 static void
3861 fatal (str)
3862 char *str;
3864 fprintf (stderr, "%s: %s\n", program_name, str);
3865 exit (1);
3868 char *
3869 xmalloc (size)
3870 unsigned size;
3872 register char *value = (char *) malloc (size);
3873 if (value == 0)
3874 fatal ("virtual memory exhausted");
3875 return value;
3878 char *
3879 xrealloc (ptr, size)
3880 char *ptr;
3881 unsigned size;
3883 register char *value = (char *) realloc (ptr, size);
3884 if (value == 0)
3885 fatal ("virtual memory exhausted");
3886 return value;
3888 #endif /* main */