Import final gcc2 snapshot (990109)
[official-gcc.git] / gcc / cplus-dem.c
blobabaa4445907865631d7a6f39294ab66a6e0913ab
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 #include <ctype.h>
32 #include <string.h>
33 #include <stdio.h>
35 #include <demangle.h>
36 #undef CURRENT_DEMANGLING_STYLE
37 #define CURRENT_DEMANGLING_STYLE work->options
39 extern char *xmalloc PARAMS((unsigned));
40 extern char *xrealloc PARAMS((char *, unsigned));
42 static const char *mystrstr PARAMS ((const char *, const char *));
44 static const char *
45 mystrstr (s1, s2)
46 const char *s1, *s2;
48 register const char *p = s1;
49 register int len = strlen (s2);
51 for (; (p = strchr (p, *s2)) != 0; p++)
53 if (strncmp (p, s2, len) == 0)
55 return (p);
58 return (0);
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 '$'.
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
75 marker symbol (FIXME). */
77 #if !defined (CPLUS_MARKER)
78 #define CPLUS_MARKER '$'
79 #endif
81 enum demangling_styles current_demangling_style = gnu_demangling;
83 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
85 void
86 set_cplus_marker_for_demangling (ch)
87 int ch;
89 cplus_markers[0] = ch;
92 /* Stuff that is shared between sub-routines.
93 Using a shared structure allows cplus_demangle to be reentrant. */
95 struct work_stuff
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 */
105 char **tmpl_argvec; /* Template function arguments. */
106 int ntmpl_args; /* The number of template function arguments. */
109 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
110 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
112 static const struct optable
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 */
189 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
190 {"max", ">?", 0}, /* old */
191 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
192 {"min", "<?", 0}, /* old */
193 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
194 {"nop", "", 0}, /* old (for operator=) */
195 {"rm", "->*", DMGL_ANSI} /* ansi */
199 typedef struct string /* Beware: these aren't required to be */
200 { /* '\0' terminated. */
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;
206 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
207 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
208 string_prepend(str, " ");}
209 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
210 string_append(str, " ");}
212 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
213 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
215 /* Prototypes for local functions */
217 static char *
218 mop_up PARAMS ((struct work_stuff *, string *, int));
220 #if 0
221 static int
222 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
223 #endif
225 static int
226 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
227 string *, int));
229 static int
230 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
231 const char **));
233 static void
234 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
236 static int
237 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
239 static int
240 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
241 int, int));
243 static int
244 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
246 static int
247 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
249 static int
250 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
252 static int
253 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
255 static int
256 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
258 static int
259 arm_special PARAMS ((struct work_stuff *, const char **, string *));
261 static void
262 string_need PARAMS ((string *, int));
264 static void
265 string_delete PARAMS ((string *));
267 static void
268 string_init PARAMS ((string *));
270 static void
271 string_clear PARAMS ((string *));
273 #if 0
274 static int
275 string_empty PARAMS ((string *));
276 #endif
278 static void
279 string_append PARAMS ((string *, const char *));
281 static void
282 string_appends PARAMS ((string *, string *));
284 static void
285 string_appendn PARAMS ((string *, const char *, int));
287 static void
288 string_prepend PARAMS ((string *, const char *));
290 static void
291 string_prependn PARAMS ((string *, const char *, int));
293 static int
294 get_count PARAMS ((const char **, int *));
296 static int
297 consume_count PARAMS ((const char **));
299 static int
300 consume_count_with_underscores PARAMS ((const char**));
302 static int
303 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
305 static int
306 do_type PARAMS ((struct work_stuff *, const char **, string *));
308 static int
309 do_arg PARAMS ((struct work_stuff *, const char **, string *));
311 static void
312 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
313 const char *));
315 static void
316 remember_type PARAMS ((struct work_stuff *, const char *, int));
318 static void
319 forget_types PARAMS ((struct work_stuff *));
321 static void
322 string_prepends PARAMS ((string *, string *));
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
327 no consumption of input and a return of 0. */
329 static int
330 consume_count (type)
331 const char **type;
333 int count = 0;
335 while (isdigit (**type))
337 count *= 10;
338 count += **type - '0';
339 (*type)++;
341 return (count);
345 /* Like consume_count, but for counts that are preceded and followed
346 by '_' if they are greater than 10. Also, -1 is returned for
347 failure, since 0 can be a valid value. */
349 static int
350 consume_count_with_underscores (mangled)
351 const char **mangled;
353 int idx;
355 if (**mangled == '_')
357 (*mangled)++;
358 if (!isdigit (**mangled))
359 return -1;
361 idx = consume_count (mangled);
362 if (**mangled != '_')
363 /* The trailing underscore was missing. */
364 return -1;
366 (*mangled)++;
368 else
370 if (**mangled < '0' || **mangled > '9')
371 return -1;
373 idx = **mangled - '0';
374 (*mangled)++;
377 return idx;
381 cplus_demangle_opname (opname, result, options)
382 const char *opname;
383 char *result;
384 int options;
386 int len, i, len1, ret;
387 string type;
388 struct work_stuff work[1];
389 const char *tem;
391 len = strlen(opname);
392 result[0] = '\0';
393 ret = 0;
394 work->options = options;
396 if (opname[0] == '_' && opname[1] == '_'
397 && opname[2] == 'o' && opname[3] == 'p')
399 /* ANSI. */
400 /* type conversion operator. */
401 tem = opname + 4;
402 if (do_type (work, &tem, &type))
404 strcat (result, "operator ");
405 strncat (result, type.b, type.p - type.b);
406 string_delete (&type);
407 ret = 1;
410 else if (opname[0] == '_' && opname[1] == '_'
411 && opname[2] >= 'a' && opname[2] <= 'z'
412 && opname[3] >= 'a' && opname[3] <= 'z')
414 if (opname[4] == '\0')
416 /* Operator. */
417 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
419 if (strlen (optable[i].in) == 2
420 && memcmp (optable[i].in, opname + 2, 2) == 0)
422 strcat (result, "operator");
423 strcat (result, optable[i].out);
424 ret = 1;
425 break;
429 else
431 if (opname[2] == 'a' && opname[5] == '\0')
433 /* Assignment. */
434 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
436 if (strlen (optable[i].in) == 3
437 && memcmp (optable[i].in, opname + 2, 3) == 0)
439 strcat (result, "operator");
440 strcat (result, optable[i].out);
441 ret = 1;
442 break;
448 else if (len >= 3
449 && opname[0] == 'o'
450 && opname[1] == 'p'
451 && strchr (cplus_markers, opname[2]) != NULL)
453 /* see if it's an assignment expression */
454 if (len >= 10 /* op$assign_ */
455 && memcmp (opname + 3, "assign_", 7) == 0)
457 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
459 len1 = len - 10;
460 if (strlen (optable[i].in) == len1
461 && memcmp (optable[i].in, opname + 10, len1) == 0)
463 strcat (result, "operator");
464 strcat (result, optable[i].out);
465 strcat (result, "=");
466 ret = 1;
467 break;
471 else
473 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
475 len1 = len - 3;
476 if (strlen (optable[i].in) == len1
477 && memcmp (optable[i].in, opname + 3, len1) == 0)
479 strcat (result, "operator");
480 strcat (result, optable[i].out);
481 ret = 1;
482 break;
487 else if (len >= 5 && memcmp (opname, "type", 4) == 0
488 && strchr (cplus_markers, opname[4]) != NULL)
490 /* type conversion operator */
491 tem = opname + 5;
492 if (do_type (work, &tem, &type))
494 strcat (result, "operator ");
495 strncat (result, type.b, type.p - type.b);
496 string_delete (&type);
497 ret = 1;
500 return ret;
503 /* Takes operator name as e.g. "++" and returns mangled
504 operator name (e.g. "postincrement_expr"), or NULL if not found.
506 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
507 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
509 const char *
510 cplus_mangle_opname (opname, options)
511 const char *opname;
512 int options;
514 int i;
515 int len;
517 len = strlen (opname);
518 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
520 if (strlen (optable[i].out) == len
521 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
522 && memcmp (optable[i].out, opname, len) == 0)
523 return optable[i].in;
525 return (0);
528 /* char *cplus_demangle (const char *mangled, int options)
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.
536 The OPTIONS arg may contain one or more of the following bits:
538 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
539 included.
540 DMGL_PARAMS Function parameters are included.
542 For example,
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"
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"
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. */
556 char *
557 cplus_demangle (mangled, options)
558 const char *mangled;
559 int options;
561 string decl;
562 int success = 0;
563 struct work_stuff work[1];
564 char *demangled = NULL;
566 if ((mangled != NULL) && (*mangled != '\0'))
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;
573 string_init (&decl);
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
580 example. */
582 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
584 success = gnu_special (work, &mangled, &decl);
586 if (!success)
588 success = demangle_prefix (work, &mangled, &decl);
590 if (success && (*mangled != '\0'))
592 success = demangle_signature (work, &mangled, &decl);
594 if (work->constructor == 2)
596 string_prepend(&decl, "global constructors keyed to ");
597 work->constructor = 0;
599 else if (work->destructor == 2)
601 string_prepend(&decl, "global destructors keyed to ");
602 work->destructor = 0;
604 demangled = mop_up (work, &decl, success);
606 return (demangled);
609 static char *
610 mop_up (work, declp, success)
611 struct work_stuff *work;
612 string *declp;
613 int success;
615 char *demangled = NULL;
617 /* Discard the remembered types, if any. */
619 forget_types (work);
620 if (work -> typevec != NULL)
622 free ((char *) work -> typevec);
624 if (work->tmpl_argvec)
626 int i;
628 for (i = 0; i < work->ntmpl_args; i++)
629 if (work->tmpl_argvec[i])
630 free ((char*) work->tmpl_argvec[i]);
632 free ((char*) work->tmpl_argvec);
635 /* If demangling was successful, ensure that the demangled string is null
636 terminated and return it. Otherwise, free the demangling decl. */
638 if (!success)
640 string_delete (declp);
642 else
644 string_appendn (declp, "", 1);
645 demangled = declp -> b;
647 return (demangled);
652 LOCAL FUNCTION
654 demangle_signature -- demangle the signature part of a mangled name
656 SYNOPSIS
658 static int
659 demangle_signature (struct work_stuff *work, const char **mangled,
660 string *declp);
662 DESCRIPTION
664 Consume and demangle the signature portion of the mangled name.
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.
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.
676 Demangling GNU style mangled names is nasty because there is no
677 explicit token that marks the start of the outermost function
678 argument list. */
680 static int
681 demangle_signature (work, mangled, declp)
682 struct work_stuff *work;
683 const char **mangled;
684 string *declp;
686 int success = 1;
687 int func_done = 0;
688 int expect_func = 0;
689 int expect_return_type = 0;
690 const char *oldmangled = NULL;
691 string trawname;
692 string tname;
694 while (success && (**mangled != '\0'))
696 switch (**mangled)
698 case 'Q':
699 oldmangled = *mangled;
700 success = demangle_qualified (work, mangled, declp, 1, 0);
701 if (success)
703 remember_type (work, oldmangled, *mangled - oldmangled);
705 if (AUTO_DEMANGLING || GNU_DEMANGLING)
707 expect_func = 1;
709 oldmangled = NULL;
710 break;
712 case 'S':
713 /* Static member function */
714 if (oldmangled == NULL)
716 oldmangled = *mangled;
718 (*mangled)++;
719 work -> static_type = 1;
720 break;
722 case 'C':
723 /* a const member function */
724 if (oldmangled == NULL)
726 oldmangled = *mangled;
728 (*mangled)++;
729 work -> const_type = 1;
730 break;
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)
736 oldmangled = *mangled;
738 success = demangle_class (work, mangled, declp);
739 if (success)
741 remember_type (work, oldmangled, *mangled - oldmangled);
743 if (AUTO_DEMANGLING || GNU_DEMANGLING)
745 expect_func = 1;
747 oldmangled = NULL;
748 break;
750 case 'F':
751 /* Function */
752 /* ARM style demangling includes a specific 'F' character after
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
755 with either style. */
757 oldmangled = NULL;
758 func_done = 1;
759 (*mangled)++;
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() */
766 if (LUCID_DEMANGLING || ARM_DEMANGLING)
768 forget_types (work);
770 success = demangle_args (work, mangled, declp);
771 break;
773 case 't':
774 /* G++ Template */
775 string_init(&trawname);
776 string_init(&tname);
777 if (oldmangled == NULL)
779 oldmangled = *mangled;
781 success = demangle_template (work, mangled, &tname, &trawname, 1);
782 if (success)
784 remember_type (work, oldmangled, *mangled - oldmangled);
786 string_append(&tname, (work -> options & DMGL_JAVA) ? "." : "::");
787 string_prepends(declp, &tname);
788 if (work -> destructor & 1)
790 string_prepend (&trawname, "~");
791 string_appends (declp, &trawname);
792 work->destructor -= 1;
794 if ((work->constructor & 1) || (work->destructor & 1))
796 string_appends (declp, &trawname);
797 work->constructor -= 1;
799 string_delete(&trawname);
800 string_delete(&tname);
801 oldmangled = NULL;
802 expect_func = 1;
803 break;
805 case '_':
806 if (GNU_DEMANGLING && expect_return_type)
808 /* Read the return type. */
809 string return_type;
810 string_init (&return_type);
812 (*mangled)++;
813 success = do_type (work, mangled, &return_type);
814 APPEND_BLANK (&return_type);
816 string_prepends (declp, &return_type);
817 string_delete (&return_type);
818 break;
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;
827 break;
829 case 'H':
830 if (GNU_DEMANGLING)
832 /* A G++ template function. Read the template arguments. */
833 success = demangle_template (work, mangled, declp, 0, 0);
834 expect_return_type = 1;
835 (*mangled)++;
836 break;
838 else
839 /* fall through */
842 default:
843 if (AUTO_DEMANGLING || GNU_DEMANGLING)
845 /* Assume we have stumbled onto the first outermost function
846 argument token, and start processing args. */
847 func_done = 1;
848 success = demangle_args (work, mangled, declp);
850 else
852 /* Non-GNU demanglers use a specific token to mark the start
853 of the outermost function argument tokens. Typically 'F',
854 for ARM-demangling, for example. So if we find something
855 we are not prepared for, it must be an error. */
856 success = 0;
858 break;
861 if (AUTO_DEMANGLING || GNU_DEMANGLING)
864 if (success && expect_func)
866 func_done = 1;
867 success = demangle_args (work, mangled, declp);
868 /* Since template include the mangling of their return types,
869 we must set expect_func to 0 so that we don't try do
870 demangle more arguments the next time we get here. */
871 expect_func = 0;
875 if (success && !func_done)
877 if (AUTO_DEMANGLING || GNU_DEMANGLING)
879 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
880 bar__3fooi is 'foo::bar(int)'. We get here when we find the
881 first case, and need to ensure that the '(void)' gets added to
882 the current declp. Note that with ARM, the first case
883 represents the name of a static data member 'foo::bar',
884 which is in the current declp, so we leave it alone. */
885 success = demangle_args (work, mangled, declp);
888 if (success && work -> static_type && PRINT_ARG_TYPES)
890 string_append (declp, " static");
892 if (success && work -> const_type && PRINT_ARG_TYPES)
894 string_append (declp, " const");
896 return (success);
899 #if 0
901 static int
902 demangle_method_args (work, mangled, declp)
903 struct work_stuff *work;
904 const char **mangled;
905 string *declp;
907 int success = 0;
909 if (work -> static_type)
911 string_append (declp, *mangled + 1);
912 *mangled += strlen (*mangled);
913 success = 1;
915 else
917 success = demangle_args (work, mangled, declp);
919 return (success);
922 #endif
924 static int
925 demangle_template (work, mangled, tname, trawname, is_type)
926 struct work_stuff *work;
927 const char **mangled;
928 string *tname;
929 string *trawname;
930 int is_type;
932 int i;
933 int is_pointer;
934 int is_real;
935 int is_integral;
936 int is_char;
937 int is_bool;
938 int r;
939 int need_comma = 0;
940 int success = 0;
941 int done;
942 const char *old_p;
943 const char *start;
944 int symbol_len;
945 int is_java_array = 0;
946 string temp;
948 (*mangled)++;
949 if (is_type)
951 start = *mangled;
952 /* get template name */
953 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
955 return (0);
957 if (trawname)
958 string_appendn (trawname, *mangled, r);
959 is_java_array = (work -> options & DMGL_JAVA)
960 && strncmp (*mangled, "JArray1Z", 8) == 0;
961 if (! is_java_array)
963 string_appendn (tname, *mangled, r);
965 *mangled += r;
967 if (!is_java_array)
968 string_append (tname, "<");
969 /* get size of template parameter list */
970 if (!get_count (mangled, &r))
972 return (0);
974 if (!is_type)
976 /* Create an array for saving the template argument values. */
977 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
978 work->ntmpl_args = r;
979 for (i = 0; i < r; i++)
980 work->tmpl_argvec[i] = 0;
982 for (i = 0; i < r; i++)
984 if (need_comma)
986 string_append (tname, ", ");
988 /* Z for type parameters */
989 if (**mangled == 'Z')
991 (*mangled)++;
992 /* temp is initialized in do_type */
993 success = do_type (work, mangled, &temp);
994 if (success)
996 string_appends (tname, &temp);
998 if (!is_type)
1000 /* Save the template argument. */
1001 int len = temp.p - temp.b;
1002 work->tmpl_argvec[i] = xmalloc (len + 1);
1003 memcpy (work->tmpl_argvec[i], temp.b, len);
1004 work->tmpl_argvec[i][len] = '\0';
1007 string_delete(&temp);
1008 if (!success)
1010 break;
1013 else
1015 string param;
1016 string* s;
1018 /* otherwise, value parameter */
1019 old_p = *mangled;
1020 is_pointer = 0;
1021 is_real = 0;
1022 is_integral = 0;
1023 is_char = 0;
1024 is_bool = 0;
1025 done = 0;
1026 /* temp is initialized in do_type */
1027 success = do_type (work, mangled, &temp);
1029 if (success)
1031 string_appends (s, &temp);
1034 string_delete(&temp);
1035 if (!success)
1037 break;
1040 string_append (s, "=");
1043 if (!is_type)
1045 s = &param;
1046 string_init (s);
1048 else
1049 s = tname;
1051 while (*old_p && !done)
1053 switch (*old_p)
1055 case 'P':
1056 case 'p':
1057 case 'R':
1058 done = is_pointer = 1;
1059 break;
1060 case 'C': /* const */
1061 case 'S': /* explicitly signed [char] */
1062 case 'U': /* unsigned */
1063 case 'V': /* volatile */
1064 case 'F': /* function */
1065 case 'M': /* member function */
1066 case 'O': /* ??? */
1067 case 'J': /* complex */
1068 old_p++;
1069 continue;
1070 case 'Q': /* qualified name */
1071 done = is_integral = 1;
1072 break;
1073 case 'T': /* remembered type */
1074 abort ();
1075 break;
1076 case 'v': /* void */
1077 abort ();
1078 break;
1079 case 'x': /* long long */
1080 case 'l': /* long */
1081 case 'i': /* int */
1082 case 's': /* short */
1083 case 'w': /* wchar_t */
1084 done = is_integral = 1;
1085 break;
1086 case 'b': /* bool */
1087 done = is_bool = 1;
1088 break;
1089 case 'c': /* char */
1090 done = is_char = 1;
1091 break;
1092 case 'r': /* long double */
1093 case 'd': /* double */
1094 case 'f': /* float */
1095 done = is_real = 1;
1096 break;
1097 default:
1098 /* it's probably user defined type, let's assume
1099 it's integral, it seems hard to figure out
1100 what it really is */
1101 done = is_integral = 1;
1104 if (**mangled == 'Y')
1106 /* The next argument is a template parameter. */
1107 int idx;
1109 (*mangled)++;
1110 idx = consume_count_with_underscores (mangled);
1111 if (idx == -1
1112 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1113 || consume_count_with_underscores (mangled) == -1)
1115 success = 0;
1116 if (!is_type)
1117 string_delete (s);
1118 break;
1120 if (work->tmpl_argvec)
1121 string_append (s, work->tmpl_argvec[idx]);
1122 else
1124 char buf[10];
1125 sprintf(buf, "T%d", idx);
1126 string_append (s, buf);
1129 else if (is_integral)
1131 if (**mangled == 'm')
1133 string_appendn (s, "-", 1);
1134 (*mangled)++;
1136 while (isdigit (**mangled))
1138 string_appendn (s, *mangled, 1);
1139 (*mangled)++;
1142 else if (is_char)
1144 char tmp[2];
1145 int val;
1146 if (**mangled == 'm')
1148 string_appendn (s, "-", 1);
1149 (*mangled)++;
1151 string_appendn (s, "'", 1);
1152 val = consume_count(mangled);
1153 if (val == 0)
1155 success = 0;
1156 if (!is_type)
1157 string_delete (s);
1158 break;
1160 tmp[0] = (char)val;
1161 tmp[1] = '\0';
1162 string_appendn (s, &tmp[0], 1);
1163 string_appendn (s, "'", 1);
1165 else if (is_bool)
1167 int val = consume_count (mangled);
1168 if (val == 0)
1169 string_appendn (s, "false", 5);
1170 else if (val == 1)
1171 string_appendn (s, "true", 4);
1172 else
1173 success = 0;
1175 else if (is_real)
1177 if (**mangled == 'm')
1179 string_appendn (s, "-", 1);
1180 (*mangled)++;
1182 while (isdigit (**mangled))
1184 string_appendn (s, *mangled, 1);
1185 (*mangled)++;
1187 if (**mangled == '.') /* fraction */
1189 string_appendn (s, ".", 1);
1190 (*mangled)++;
1191 while (isdigit (**mangled))
1193 string_appendn (s, *mangled, 1);
1194 (*mangled)++;
1197 if (**mangled == 'e') /* exponent */
1199 string_appendn (s, "e", 1);
1200 (*mangled)++;
1201 while (isdigit (**mangled))
1203 string_appendn (s, *mangled, 1);
1204 (*mangled)++;
1208 else if (is_pointer)
1210 symbol_len = consume_count (mangled);
1211 if (symbol_len == 0)
1213 success = 0;
1214 if (!is_type)
1215 string_delete (s);
1216 break;
1218 if (symbol_len == 0)
1219 string_appendn (s, "0", 1);
1220 else
1222 char *p = xmalloc (symbol_len + 1), *q;
1223 strncpy (p, *mangled, symbol_len);
1224 p [symbol_len] = '\0';
1225 q = cplus_demangle (p, work->options);
1226 string_appendn (s, "&", 1);
1227 if (q)
1229 string_append (s, q);
1230 free (q);
1232 else
1233 string_append (s, p);
1234 free (p);
1236 *mangled += symbol_len;
1238 if (!is_type)
1240 int len = s->p - s->b;
1241 work->tmpl_argvec[i] = xmalloc (len + 1);
1242 memcpy (work->tmpl_argvec[i], s->b, len);
1243 work->tmpl_argvec[i][len] = '\0';
1245 string_appends (tname, s);
1246 string_delete (s);
1249 need_comma = 1;
1251 if (is_java_array)
1253 string_append (tname, "[]");
1255 else
1257 if (tname->p[-1] == '>')
1258 string_append (tname, " ");
1259 string_append (tname, ">");
1263 if (work -> static_type)
1265 string_append (declp, *mangled + 1);
1266 *mangled += strlen (*mangled);
1267 success = 1;
1269 else
1271 success = demangle_args (work, mangled, declp);
1275 return (success);
1278 static int
1279 arm_pt (work, mangled, n, anchor, args)
1280 struct work_stuff *work;
1281 const char *mangled;
1282 int n;
1283 const char **anchor, **args;
1285 /* ARM template? */
1286 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1288 int len;
1289 *args = *anchor + 6;
1290 len = consume_count (args);
1291 if (*args + len == mangled + n && **args == '_')
1293 ++*args;
1294 return 1;
1297 return 0;
1300 static void
1301 demangle_arm_pt (work, mangled, n, declp)
1302 struct work_stuff *work;
1303 const char **mangled;
1304 int n;
1305 string *declp;
1307 const char *p;
1308 const char *args;
1309 const char *e = *mangled + n;
1311 /* ARM template? */
1312 if (arm_pt (work, *mangled, n, &p, &args))
1314 string arg;
1315 string_init (&arg);
1316 string_appendn (declp, *mangled, p - *mangled);
1317 string_append (declp, "<");
1318 /* should do error checking here */
1319 while (args < e) {
1320 string_clear (&arg);
1321 do_type (work, &args, &arg);
1322 string_appends (declp, &arg);
1323 string_append (declp, ",");
1325 string_delete (&arg);
1326 --declp->p;
1327 string_append (declp, ">");
1329 else
1331 string_appendn (declp, *mangled, n);
1333 *mangled += n;
1336 static int
1337 demangle_class_name (work, mangled, declp)
1338 struct work_stuff *work;
1339 const char **mangled;
1340 string *declp;
1342 int n;
1343 int success = 0;
1345 n = consume_count (mangled);
1346 if (strlen (*mangled) >= n)
1348 demangle_arm_pt (work, mangled, n, declp);
1349 success = 1;
1352 return (success);
1357 LOCAL FUNCTION
1359 demangle_class -- demangle a mangled class sequence
1361 SYNOPSIS
1363 static int
1364 demangle_class (struct work_stuff *work, const char **mangled,
1365 strint *declp)
1367 DESCRIPTION
1369 DECLP points to the buffer into which demangling is being done.
1371 *MANGLED points to the current token to be demangled. On input,
1372 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1373 On exit, it points to the next token after the mangled class on
1374 success, or the first unconsumed token on failure.
1376 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1377 we are demangling a constructor or destructor. In this case
1378 we prepend "class::class" or "class::~class" to DECLP.
1380 Otherwise, we prepend "class::" to the current DECLP.
1382 Reset the constructor/destructor flags once they have been
1383 "consumed". This allows demangle_class to be called later during
1384 the same demangling, to do normal class demangling.
1386 Returns 1 if demangling is successful, 0 otherwise.
1390 static int
1391 demangle_class (work, mangled, declp)
1392 struct work_stuff *work;
1393 const char **mangled;
1394 string *declp;
1396 int success = 0;
1397 string class_name;
1399 string_init (&class_name);
1400 if (demangle_class_name (work, mangled, &class_name))
1402 if ((work->constructor & 1) || (work->destructor & 1))
1404 string_prepends (declp, &class_name);
1405 if (work -> destructor & 1)
1407 string_prepend (declp, "~");
1408 work -> destructor -= 1;
1410 else
1412 work -> constructor -= 1;
1415 string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1416 string_prepends (declp, &class_name);
1417 success = 1;
1419 string_delete (&class_name);
1420 return (success);
1425 LOCAL FUNCTION
1427 demangle_prefix -- consume the mangled name prefix and find signature
1429 SYNOPSIS
1431 static int
1432 demangle_prefix (struct work_stuff *work, const char **mangled,
1433 string *declp);
1435 DESCRIPTION
1437 Consume and demangle the prefix of the mangled name.
1439 DECLP points to the string buffer into which demangled output is
1440 placed. On entry, the buffer is empty. On exit it contains
1441 the root function name, the demangled operator name, or in some
1442 special cases either nothing or the completely demangled result.
1444 MANGLED points to the current pointer into the mangled name. As each
1445 token of the mangled name is consumed, it is updated. Upon entry
1446 the current mangled name pointer points to the first character of
1447 the mangled name. Upon exit, it should point to the first character
1448 of the signature if demangling was successful, or to the first
1449 unconsumed character if demangling of the prefix was unsuccessful.
1451 Returns 1 on success, 0 otherwise.
1454 static int
1455 demangle_prefix (work, mangled, declp)
1456 struct work_stuff *work;
1457 const char **mangled;
1458 string *declp;
1460 int success = 1;
1461 const char *scan;
1462 int i;
1464 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1466 char *marker = strchr (cplus_markers, (*mangled)[8]);
1467 if (marker != NULL && *marker == (*mangled)[10])
1469 if ((*mangled)[9] == 'D')
1471 /* it's a GNU global destructor to be executed at program exit */
1472 (*mangled) += 11;
1473 work->destructor = 2;
1474 if (gnu_special (work, mangled, declp))
1475 return success;
1477 else if ((*mangled)[9] == 'I')
1479 /* it's a GNU global constructor to be executed at program init */
1480 (*mangled) += 11;
1481 work->constructor = 2;
1482 if (gnu_special (work, mangled, declp))
1483 return success;
1487 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1489 /* it's a ARM global destructor to be executed at program exit */
1490 (*mangled) += 7;
1491 work->destructor = 2;
1493 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1495 /* it's a ARM global constructor to be executed at program initial */
1496 (*mangled) += 7;
1497 work->constructor = 2;
1500 /* This block of code is a reduction in strength time optimization
1502 scan = mystrstr (*mangled, "__"); */
1505 scan = *mangled;
1507 do {
1508 scan = strchr (scan, '_');
1509 } while (scan != NULL && *++scan != '_');
1511 if (scan != NULL) --scan;
1514 if (scan != NULL)
1516 /* We found a sequence of two or more '_', ensure that we start at
1517 the last pair in the sequence. */
1518 i = strspn (scan, "_");
1519 if (i > 2)
1521 scan += (i - 2);
1525 if (scan == NULL)
1527 success = 0;
1529 else if (work -> static_type)
1531 if (!isdigit (scan[0]) && (scan[0] != 't'))
1533 success = 0;
1536 else if ((scan == *mangled)
1537 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
1539 /* The ARM says nothing about the mangling of local variables.
1540 But cfront mangles local variables by prepending __<nesting_level>
1541 to them. As an extension to ARM demangling we handle this case. */
1542 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1544 *mangled = scan + 2;
1545 consume_count (mangled);
1546 string_append (declp, *mangled);
1547 *mangled += strlen (*mangled);
1548 success = 1;
1550 else
1552 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1553 names like __Q2_3foo3bar for nested type names. So don't accept
1554 this style of constructor for cfront demangling. */
1555 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1556 work -> constructor += 1;
1557 *mangled = scan + 2;
1560 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1562 /* Mangled name starts with "__". Skip over any leading '_' characters,
1563 then find the next "__" that separates the prefix from the signature.
1565 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1566 || (arm_special (work, mangled, declp) == 0))
1568 while (*scan == '_')
1570 scan++;
1572 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1574 /* No separator (I.E. "__not_mangled"), or empty signature
1575 (I.E. "__not_mangled_either__") */
1576 success = 0;
1578 else
1580 demangle_function_name (work, mangled, declp, scan);
1584 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1586 /* Cfront-style parameterized type. Handled later as a signature. */
1587 success = 1;
1589 /* ARM template? */
1590 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1592 else if (*(scan + 2) != '\0')
1594 /* Mangled name does not start with "__" but does have one somewhere
1595 in there with non empty stuff after it. Looks like a global
1596 function name. */
1597 demangle_function_name (work, mangled, declp, scan);
1599 else
1601 /* Doesn't look like a mangled name */
1602 success = 0;
1605 if (!success && (work->constructor == 2 || work->destructor == 2))
1607 string_append (declp, *mangled);
1608 *mangled += strlen (*mangled);
1609 success = 1;
1611 return (success);
1616 LOCAL FUNCTION
1618 gnu_special -- special handling of gnu mangled strings
1620 SYNOPSIS
1622 static int
1623 gnu_special (struct work_stuff *work, const char **mangled,
1624 string *declp);
1627 DESCRIPTION
1629 Process some special GNU style mangling forms that don't fit
1630 the normal pattern. For example:
1632 _$_3foo (destructor for class foo)
1633 _vt$foo (foo virtual table)
1634 _vt$foo$bar (foo::bar virtual table)
1635 __vt_foo (foo virtual table, new style with thunks)
1636 _3foo$varname (static data member)
1637 _Q22rs2tu$vw (static data member)
1638 __t6vector1Zii (constructor with template)
1639 __thunk_4__$_7ostream (virtual function thunk)
1642 static int
1643 gnu_special (work, mangled, declp)
1644 struct work_stuff *work;
1645 const char **mangled;
1646 string *declp;
1648 int n;
1649 int success = 1;
1650 const char *p;
1652 if ((*mangled)[0] == '_'
1653 && strchr (cplus_markers, (*mangled)[1]) != NULL
1654 && (*mangled)[2] == '_')
1656 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1657 (*mangled) += 3;
1658 work -> destructor += 1;
1660 else if ((*mangled)[0] == '_'
1661 && (((*mangled)[1] == '_'
1662 && (*mangled)[2] == 'v'
1663 && (*mangled)[3] == 't'
1664 && (*mangled)[4] == '_')
1665 || ((*mangled)[1] == 'v'
1666 && (*mangled)[2] == 't'
1667 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1669 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1670 and create the decl. Note that we consume the entire mangled
1671 input string, which means that demangle_signature has no work
1672 to do. */
1673 if ((*mangled)[2] == 'v')
1674 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1675 else
1676 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1677 while (**mangled != '\0')
1679 p = strpbrk (*mangled, cplus_markers);
1680 switch (**mangled)
1682 case 'Q':
1683 success = demangle_qualified (work, mangled, declp, 0, 1);
1684 break;
1685 case 't':
1686 success = demangle_template (work, mangled, declp, 0, 1);
1687 break;
1688 default:
1689 if (isdigit(*mangled[0]))
1691 n = consume_count(mangled);
1693 else
1695 n = strcspn (*mangled, cplus_markers);
1697 string_appendn (declp, *mangled, n);
1698 (*mangled) += n;
1701 if (success && ((p == NULL) || (p == *mangled)))
1703 if (p != NULL)
1705 string_append (declp,
1706 (work -> options & DMGL_JAVA) ? "." : "::");
1707 (*mangled)++;
1710 else
1712 success = 0;
1713 break;
1716 if (success)
1717 string_append (declp, " virtual table");
1719 else if ((*mangled)[0] == '_'
1720 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1721 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1723 /* static data member, "_3foo$varname" for example */
1724 (*mangled)++;
1725 switch (**mangled)
1727 case 'Q':
1728 success = demangle_qualified (work, mangled, declp, 0, 1);
1729 break;
1730 case 't':
1731 success = demangle_template (work, mangled, declp, 0, 1);
1732 break;
1733 default:
1734 n = consume_count (mangled);
1735 string_appendn (declp, *mangled, n);
1736 (*mangled) += n;
1738 if (success && (p == *mangled))
1740 /* Consumed everything up to the cplus_marker, append the
1741 variable name. */
1742 (*mangled)++;
1743 string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1744 n = strlen (*mangled);
1745 string_appendn (declp, *mangled, n);
1746 (*mangled) += n;
1748 else
1750 success = 0;
1753 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1755 int delta = ((*mangled) += 8, consume_count (mangled));
1756 char *method = cplus_demangle (++*mangled, work->options);
1757 if (method)
1759 char buf[50];
1760 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1761 string_append (declp, buf);
1762 string_append (declp, method);
1763 free (method);
1764 n = strlen (*mangled);
1765 (*mangled) += n;
1767 else
1769 success = 0;
1772 else if (strncmp (*mangled, "__t", 3) == 0
1773 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1775 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1776 (*mangled) += 4;
1777 switch (**mangled)
1779 case 'Q':
1780 success = demangle_qualified (work, mangled, declp, 0, 1);
1781 break;
1782 case 't':
1783 success = demangle_template (work, mangled, declp, 0, 1);
1784 break;
1785 default:
1786 success = demangle_fund_type (work, mangled, declp);
1787 break;
1789 if (success && **mangled != '\0')
1790 success = 0;
1791 if (success)
1792 string_append (declp, p);
1794 else
1796 success = 0;
1798 return (success);
1803 LOCAL FUNCTION
1805 arm_special -- special handling of ARM/lucid mangled strings
1807 SYNOPSIS
1809 static int
1810 arm_special (struct work_stuff *work, const char **mangled,
1811 string *declp);
1814 DESCRIPTION
1816 Process some special ARM style mangling forms that don't fit
1817 the normal pattern. For example:
1819 __vtbl__3foo (foo virtual table)
1820 __vtbl__3foo__3bar (bar::foo virtual table)
1824 static int
1825 arm_special (work, mangled, declp)
1826 struct work_stuff *work;
1827 const char **mangled;
1828 string *declp;
1830 int n;
1831 int success = 1;
1832 const char *scan;
1834 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1836 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1837 and create the decl. Note that we consume the entire mangled
1838 input string, which means that demangle_signature has no work
1839 to do. */
1840 scan = *mangled + ARM_VTABLE_STRLEN;
1841 while (*scan != '\0') /* first check it can be demangled */
1843 n = consume_count (&scan);
1844 if (n==0)
1846 return (0); /* no good */
1848 scan += n;
1849 if (scan[0] == '_' && scan[1] == '_')
1851 scan += 2;
1854 (*mangled) += ARM_VTABLE_STRLEN;
1855 while (**mangled != '\0')
1857 n = consume_count (mangled);
1858 string_prependn (declp, *mangled, n);
1859 (*mangled) += n;
1860 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1862 string_prepend (declp, "::");
1863 (*mangled) += 2;
1866 string_append (declp, " virtual table");
1868 else
1870 success = 0;
1872 return (success);
1877 LOCAL FUNCTION
1879 demangle_qualified -- demangle 'Q' qualified name strings
1881 SYNOPSIS
1883 static int
1884 demangle_qualified (struct work_stuff *, const char *mangled,
1885 string *result, int isfuncname, int append);
1887 DESCRIPTION
1889 Demangle a qualified name, such as "Q25Outer5Inner" which is
1890 the mangled form of "Outer::Inner". The demangled output is
1891 prepended or appended to the result string according to the
1892 state of the append flag.
1894 If isfuncname is nonzero, then the qualified name we are building
1895 is going to be used as a member function name, so if it is a
1896 constructor or destructor function, append an appropriate
1897 constructor or destructor name. I.E. for the above example,
1898 the result for use as a constructor is "Outer::Inner::Inner"
1899 and the result for use as a destructor is "Outer::Inner::~Inner".
1901 BUGS
1903 Numeric conversion is ASCII dependent (FIXME).
1907 static int
1908 demangle_qualified (work, mangled, result, isfuncname, append)
1909 struct work_stuff *work;
1910 const char **mangled;
1911 string *result;
1912 int isfuncname;
1913 int append;
1915 int qualifiers;
1916 int namelength;
1917 int success = 1;
1918 const char *p;
1919 char num[2];
1920 string temp;
1922 string_init (&temp);
1923 switch ((*mangled)[1])
1925 case '_':
1926 /* GNU mangled name with more than 9 classes. The count is preceded
1927 by an underscore (to distinguish it from the <= 9 case) and followed
1928 by an underscore. */
1929 p = *mangled + 2;
1930 qualifiers = atoi (p);
1931 if (!isdigit (*p) || *p == '0')
1932 success = 0;
1934 /* Skip the digits. */
1935 while (isdigit (*p))
1936 ++p;
1938 if (*p != '_')
1939 success = 0;
1941 *mangled = p + 1;
1942 break;
1944 case '1':
1945 case '2':
1946 case '3':
1947 case '4':
1948 case '5':
1949 case '6':
1950 case '7':
1951 case '8':
1952 case '9':
1953 /* The count is in a single digit. */
1954 num[0] = (*mangled)[1];
1955 num[1] = '\0';
1956 qualifiers = atoi (num);
1958 /* If there is an underscore after the digit, skip it. This is
1959 said to be for ARM-qualified names, but the ARM makes no
1960 mention of such an underscore. Perhaps cfront uses one. */
1961 if ((*mangled)[2] == '_')
1963 (*mangled)++;
1965 (*mangled) += 2;
1966 break;
1968 case '0':
1969 default:
1970 success = 0;
1973 if (!success)
1974 return success;
1976 /* Pick off the names and collect them in the temp buffer in the order
1977 in which they are found, separated by '::'. */
1979 while (qualifiers-- > 0)
1981 if (*mangled[0] == '_')
1982 *mangled = *mangled + 1;
1983 if (*mangled[0] == 't')
1985 success = demangle_template(work, mangled, &temp, 0, 1);
1986 if (!success) break;
1988 else if (*mangled[0] == 'X')
1990 success = do_type (work, mangled, &temp);
1991 if (!success) break;
1993 else
1995 namelength = consume_count (mangled);
1996 if (strlen (*mangled) < namelength)
1998 /* Simple sanity check failed */
1999 success = 0;
2000 break;
2002 string_appendn (&temp, *mangled, namelength);
2003 *mangled += namelength;
2005 if (qualifiers > 0)
2007 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2011 /* If we are using the result as a function name, we need to append
2012 the appropriate '::' separated constructor or destructor name.
2013 We do this here because this is the most convenient place, where
2014 we already have a pointer to the name and the length of the name. */
2016 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2018 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2019 if (work -> destructor & 1)
2021 string_append (&temp, "~");
2023 string_appendn (&temp, (*mangled) - namelength, namelength);
2026 /* Now either prepend the temp buffer to the result, or append it,
2027 depending upon the state of the append flag. */
2029 if (append)
2031 string_appends (result, &temp);
2033 else
2035 if (!STRING_EMPTY (result))
2037 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2039 string_prepends (result, &temp);
2042 string_delete (&temp);
2043 return (success);
2048 LOCAL FUNCTION
2050 get_count -- convert an ascii count to integer, consuming tokens
2052 SYNOPSIS
2054 static int
2055 get_count (const char **type, int *count)
2057 DESCRIPTION
2059 Return 0 if no conversion is performed, 1 if a string is converted.
2062 static int
2063 get_count (type, count)
2064 const char **type;
2065 int *count;
2067 const char *p;
2068 int n;
2070 if (!isdigit (**type))
2072 return (0);
2074 else
2076 *count = **type - '0';
2077 (*type)++;
2078 if (isdigit (**type))
2080 p = *type;
2081 n = *count;
2084 n *= 10;
2085 n += *p - '0';
2086 p++;
2088 while (isdigit (*p));
2089 if (*p == '_')
2091 *type = p + 1;
2092 *count = n;
2096 return (1);
2099 /* result will be initialised here; it will be freed on failure */
2101 static int
2102 do_type (work, mangled, result)
2103 struct work_stuff *work;
2104 const char **mangled;
2105 string *result;
2107 int n;
2108 int done;
2109 int success;
2110 string decl;
2111 const char *remembered_type;
2112 int constp;
2113 int volatilep;
2115 string_init (&decl);
2116 string_init (result);
2118 done = 0;
2119 success = 1;
2120 while (success && !done)
2122 int member;
2123 switch (**mangled)
2126 /* A pointer type */
2127 case 'P':
2128 case 'p':
2129 (*mangled)++;
2130 if (! (work -> options & DMGL_JAVA))
2131 string_prepend (&decl, "*");
2132 break;
2134 /* A reference type */
2135 case 'R':
2136 (*mangled)++;
2137 string_prepend (&decl, "&");
2138 break;
2140 /* An array */
2141 case 'A':
2143 const char *p = ++(*mangled);
2145 string_prepend (&decl, "(");
2146 string_append (&decl, ")[");
2147 /* Copy anything up until the next underscore (the size of the
2148 array). */
2149 while (**mangled && **mangled != '_')
2150 ++(*mangled);
2151 if (**mangled == '_')
2153 string_appendn (&decl, p, *mangled - p);
2154 string_append (&decl, "]");
2155 *mangled += 1;
2157 else
2158 success = 0;
2159 break;
2162 /* A back reference to a previously seen type */
2163 case 'T':
2164 (*mangled)++;
2165 if (!get_count (mangled, &n) || n >= work -> ntypes)
2167 success = 0;
2169 else
2171 remembered_type = work -> typevec[n];
2172 mangled = &remembered_type;
2174 break;
2176 /* A function */
2177 case 'F':
2178 (*mangled)++;
2179 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2181 string_prepend (&decl, "(");
2182 string_append (&decl, ")");
2184 /* After picking off the function args, we expect to either find the
2185 function return type (preceded by an '_') or the end of the
2186 string. */
2187 if (!demangle_args (work, mangled, &decl)
2188 || (**mangled != '_' && **mangled != '\0'))
2190 success = 0;
2192 if (success && (**mangled == '_'))
2194 (*mangled)++;
2196 break;
2198 case 'M':
2199 case 'O':
2201 constp = 0;
2202 volatilep = 0;
2204 member = **mangled == 'M';
2205 (*mangled)++;
2206 if (!isdigit (**mangled) && **mangled != 't')
2208 success = 0;
2209 break;
2212 string_append (&decl, ")");
2213 string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::");
2214 if (isdigit (**mangled))
2216 n = consume_count (mangled);
2217 if (strlen (*mangled) < n)
2219 success = 0;
2220 break;
2222 string_prependn (&decl, *mangled, n);
2223 *mangled += n;
2225 else
2227 string temp;
2228 string_init (&temp);
2229 success = demangle_template (work, mangled, &temp, NULL, 1);
2230 if (success)
2232 string_prependn (&decl, temp.b, temp.p - temp.b);
2233 string_clear (&temp);
2235 else
2236 break;
2238 string_prepend (&decl, "(");
2239 if (member)
2241 if (**mangled == 'C')
2243 (*mangled)++;
2244 constp = 1;
2246 if (**mangled == 'V')
2248 (*mangled)++;
2249 volatilep = 1;
2251 if (*(*mangled)++ != 'F')
2253 success = 0;
2254 break;
2257 if ((member && !demangle_args (work, mangled, &decl))
2258 || **mangled != '_')
2260 success = 0;
2261 break;
2263 (*mangled)++;
2264 if (! PRINT_ANSI_QUALIFIERS)
2266 break;
2268 if (constp)
2270 APPEND_BLANK (&decl);
2271 string_append (&decl, "const");
2273 if (volatilep)
2275 APPEND_BLANK (&decl);
2276 string_append (&decl, "volatile");
2278 break;
2280 case 'G':
2281 (*mangled)++;
2282 break;
2284 case 'C':
2285 (*mangled)++;
2287 if ((*mangled)[1] == 'P')
2290 if (PRINT_ANSI_QUALIFIERS)
2292 if (!STRING_EMPTY (&decl))
2294 string_prepend (&decl, " ");
2296 string_prepend (&decl, "const");
2298 break;
2303 /* fall through */
2304 default:
2305 done = 1;
2306 break;
2310 switch (**mangled)
2312 /* A qualified name, such as "Outer::Inner". */
2313 case 'Q':
2314 success = demangle_qualified (work, mangled, result, 0, 1);
2315 break;
2317 case 'X':
2318 case 'Y':
2319 /* A template parm. We substitute the corresponding argument. */
2321 int idx;
2322 int lvl;
2324 (*mangled)++;
2325 idx = consume_count_with_underscores (mangled);
2327 if (idx == -1
2328 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2329 || consume_count_with_underscores (mangled) == -1)
2331 success = 0;
2332 break;
2335 if (work->tmpl_argvec)
2336 string_append (result, work->tmpl_argvec[idx]);
2337 else
2339 char buf[10];
2340 sprintf(buf, "T%d", idx);
2341 string_append (result, buf);
2344 success = 1;
2346 break;
2348 default:
2349 success = demangle_fund_type (work, mangled, result);
2350 break;
2353 if (success)
2355 if (!STRING_EMPTY (&decl))
2357 string_append (result, " ");
2358 string_appends (result, &decl);
2361 else
2363 string_delete (result);
2365 string_delete (&decl);
2366 return (success);
2369 /* Given a pointer to a type string that represents a fundamental type
2370 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2371 string in which the demangled output is being built in RESULT, and
2372 the WORK structure, decode the types and add them to the result.
2374 For example:
2376 "Ci" => "const int"
2377 "Sl" => "signed long"
2378 "CUs" => "const unsigned short"
2382 static int
2383 demangle_fund_type (work, mangled, result)
2384 struct work_stuff *work;
2385 const char **mangled;
2386 string *result;
2388 int done = 0;
2389 int success = 1;
2391 /* First pick off any type qualifiers. There can be more than one. */
2393 while (!done)
2395 switch (**mangled)
2397 case 'C':
2398 (*mangled)++;
2399 if (PRINT_ANSI_QUALIFIERS)
2401 APPEND_BLANK (result);
2402 string_append (result, "const");
2404 break;
2405 case 'U':
2406 (*mangled)++;
2407 APPEND_BLANK (result);
2408 string_append (result, "unsigned");
2409 break;
2410 case 'S': /* signed char only */
2411 (*mangled)++;
2412 APPEND_BLANK (result);
2413 string_append (result, "signed");
2414 break;
2415 case 'V':
2416 (*mangled)++;
2417 if (PRINT_ANSI_QUALIFIERS)
2419 APPEND_BLANK (result);
2420 string_append (result, "volatile");
2422 break;
2423 case 'J':
2424 (*mangled)++;
2425 APPEND_BLANK (result);
2426 string_append (result, "__complex");
2427 break;
2428 default:
2429 done = 1;
2430 break;
2434 /* Now pick off the fundamental type. There can be only one. */
2436 switch (**mangled)
2438 case '\0':
2439 case '_':
2440 break;
2441 case 'v':
2442 (*mangled)++;
2443 APPEND_BLANK (result);
2444 string_append (result, "void");
2445 break;
2446 case 'x':
2447 (*mangled)++;
2448 APPEND_BLANK (result);
2449 string_append (result, "long long");
2450 break;
2451 case 'l':
2452 (*mangled)++;
2453 APPEND_BLANK (result);
2454 string_append (result, "long");
2455 break;
2456 case 'i':
2457 (*mangled)++;
2458 APPEND_BLANK (result);
2459 string_append (result, "int");
2460 break;
2461 case 's':
2462 (*mangled)++;
2463 APPEND_BLANK (result);
2464 string_append (result, "short");
2465 break;
2466 case 'b':
2467 (*mangled)++;
2468 APPEND_BLANK (result);
2469 string_append (result, "bool");
2470 break;
2471 case 'c':
2472 (*mangled)++;
2473 APPEND_BLANK (result);
2474 string_append (result, "char");
2475 break;
2476 case 'w':
2477 (*mangled)++;
2478 APPEND_BLANK (result);
2479 string_append (result, "wchar_t");
2480 break;
2481 case 'r':
2482 (*mangled)++;
2483 APPEND_BLANK (result);
2484 string_append (result, "long double");
2485 break;
2486 case 'd':
2487 (*mangled)++;
2488 APPEND_BLANK (result);
2489 string_append (result, "double");
2490 break;
2491 case 'f':
2492 (*mangled)++;
2493 APPEND_BLANK (result);
2494 string_append (result, "float");
2495 break;
2496 case 'G':
2497 (*mangled)++;
2498 if (!isdigit (**mangled))
2500 success = 0;
2501 break;
2503 /* fall through */
2504 /* An explicit type, such as "6mytype" or "7integer" */
2505 case '0':
2506 case '1':
2507 case '2':
2508 case '3':
2509 case '4':
2510 case '5':
2511 case '6':
2512 case '7':
2513 case '8':
2514 case '9':
2515 APPEND_BLANK (result);
2516 if (!demangle_class_name (work, mangled, result)) {
2517 --result->p;
2518 success = 0;
2520 break;
2521 case 't':
2522 success = demangle_template(work,mangled, result, 0, 1);
2523 break;
2524 default:
2525 success = 0;
2526 break;
2529 return (success);
2532 /* `result' will be initialized in do_type; it will be freed on failure */
2534 static int
2535 do_arg (work, mangled, result)
2536 struct work_stuff *work;
2537 const char **mangled;
2538 string *result;
2540 const char *start = *mangled;
2542 if (!do_type (work, mangled, result))
2544 return (0);
2546 else
2548 remember_type (work, start, *mangled - start);
2549 return (1);
2553 static void
2554 remember_type (work, start, len)
2555 struct work_stuff *work;
2556 const char *start;
2557 int len;
2559 char *tem;
2561 if (work -> ntypes >= work -> typevec_size)
2563 if (work -> typevec_size == 0)
2565 work -> typevec_size = 3;
2566 work -> typevec
2567 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2569 else
2571 work -> typevec_size *= 2;
2572 work -> typevec
2573 = (char **) xrealloc ((char *)work -> typevec,
2574 sizeof (char *) * work -> typevec_size);
2577 tem = xmalloc (len + 1);
2578 memcpy (tem, start, len);
2579 tem[len] = '\0';
2580 work -> typevec[work -> ntypes++] = tem;
2583 /* Forget the remembered types, but not the type vector itself. */
2585 static void
2586 forget_types (work)
2587 struct work_stuff *work;
2589 int i;
2591 while (work -> ntypes > 0)
2593 i = --(work -> ntypes);
2594 if (work -> typevec[i] != NULL)
2596 free (work -> typevec[i]);
2597 work -> typevec[i] = NULL;
2602 /* Process the argument list part of the signature, after any class spec
2603 has been consumed, as well as the first 'F' character (if any). For
2604 example:
2606 "__als__3fooRT0" => process "RT0"
2607 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2609 DECLP must be already initialised, usually non-empty. It won't be freed
2610 on failure.
2612 Note that g++ differs significantly from ARM and lucid style mangling
2613 with regards to references to previously seen types. For example, given
2614 the source fragment:
2616 class foo {
2617 public:
2618 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2621 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2622 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2624 g++ produces the names:
2626 __3fooiRT0iT2iT2
2627 foo__FiR3fooiT1iT1
2629 while lcc (and presumably other ARM style compilers as well) produces:
2631 foo__FiR3fooT1T2T1T2
2632 __ct__3fooFiR3fooT1T2T1T2
2634 Note that g++ bases its type numbers starting at zero and counts all
2635 previously seen types, while lucid/ARM bases its type numbers starting
2636 at one and only considers types after it has seen the 'F' character
2637 indicating the start of the function args. For lucid/ARM style, we
2638 account for this difference by discarding any previously seen types when
2639 we see the 'F' character, and subtracting one from the type number
2640 reference.
2644 static int
2645 demangle_args (work, mangled, declp)
2646 struct work_stuff *work;
2647 const char **mangled;
2648 string *declp;
2650 string arg;
2651 int need_comma = 0;
2652 int r;
2653 int t;
2654 const char *tem;
2655 char temptype;
2657 if (PRINT_ARG_TYPES)
2659 string_append (declp, "(");
2660 if (**mangled == '\0')
2662 string_append (declp, "void");
2666 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2668 if ((**mangled == 'N') || (**mangled == 'T'))
2670 temptype = *(*mangled)++;
2672 if (temptype == 'N')
2674 if (!get_count (mangled, &r))
2676 return (0);
2679 else
2681 r = 1;
2683 if (ARM_DEMANGLING && work -> ntypes >= 10)
2685 /* If we have 10 or more types we might have more than a 1 digit
2686 index so we'll have to consume the whole count here. This
2687 will lose if the next thing is a type name preceded by a
2688 count but it's impossible to demangle that case properly
2689 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2690 Pc, ...)" or "(..., type12, char *, ...)" */
2691 if ((t = consume_count(mangled)) == 0)
2693 return (0);
2696 else
2698 if (!get_count (mangled, &t))
2700 return (0);
2703 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2705 t--;
2707 /* Validate the type index. Protect against illegal indices from
2708 malformed type strings. */
2709 if ((t < 0) || (t >= work -> ntypes))
2711 return (0);
2713 while (--r >= 0)
2715 tem = work -> typevec[t];
2716 if (need_comma && PRINT_ARG_TYPES)
2718 string_append (declp, ", ");
2720 if (!do_arg (work, &tem, &arg))
2722 return (0);
2724 if (PRINT_ARG_TYPES)
2726 string_appends (declp, &arg);
2728 string_delete (&arg);
2729 need_comma = 1;
2732 else
2734 if (need_comma & PRINT_ARG_TYPES)
2736 string_append (declp, ", ");
2738 if (!do_arg (work, mangled, &arg))
2740 return (0);
2742 if (PRINT_ARG_TYPES)
2744 string_appends (declp, &arg);
2746 string_delete (&arg);
2747 need_comma = 1;
2751 if (**mangled == 'e')
2753 (*mangled)++;
2754 if (PRINT_ARG_TYPES)
2756 if (need_comma)
2758 string_append (declp, ",");
2760 string_append (declp, "...");
2764 if (PRINT_ARG_TYPES)
2766 string_append (declp, ")");
2768 return (1);
2771 static void
2772 demangle_function_name (work, mangled, declp, scan)
2773 struct work_stuff *work;
2774 const char **mangled;
2775 string *declp;
2776 const char *scan;
2778 int i;
2779 int len;
2780 string type;
2781 const char *tem;
2783 string_appendn (declp, (*mangled), scan - (*mangled));
2784 string_need (declp, 1);
2785 *(declp -> p) = '\0';
2787 /* Consume the function name, including the "__" separating the name
2788 from the signature. We are guaranteed that SCAN points to the
2789 separator. */
2791 (*mangled) = scan + 2;
2793 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2796 /* See if we have an ARM style constructor or destructor operator.
2797 If so, then just record it, clear the decl, and return.
2798 We can't build the actual constructor/destructor decl until later,
2799 when we recover the class name from the signature. */
2801 if (strcmp (declp -> b, "__ct") == 0)
2803 work -> constructor += 1;
2804 string_clear (declp);
2805 return;
2807 else if (strcmp (declp -> b, "__dt") == 0)
2809 work -> destructor += 1;
2810 string_clear (declp);
2811 return;
2815 if (declp->p - declp->b >= 3
2816 && declp->b[0] == 'o'
2817 && declp->b[1] == 'p'
2818 && strchr (cplus_markers, declp->b[2]) != NULL)
2820 /* see if it's an assignment expression */
2821 if (declp->p - declp->b >= 10 /* op$assign_ */
2822 && memcmp (declp->b + 3, "assign_", 7) == 0)
2824 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2826 len = declp->p - declp->b - 10;
2827 if (strlen (optable[i].in) == len
2828 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2830 string_clear (declp);
2831 string_append (declp, "operator");
2832 string_append (declp, optable[i].out);
2833 string_append (declp, "=");
2834 break;
2838 else
2840 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2842 int len = declp->p - declp->b - 3;
2843 if (strlen (optable[i].in) == len
2844 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2846 string_clear (declp);
2847 string_append (declp, "operator");
2848 string_append (declp, optable[i].out);
2849 break;
2854 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2855 && strchr (cplus_markers, declp->b[4]) != NULL)
2857 /* type conversion operator */
2858 tem = declp->b + 5;
2859 if (do_type (work, &tem, &type))
2861 string_clear (declp);
2862 string_append (declp, "operator ");
2863 string_appends (declp, &type);
2864 string_delete (&type);
2867 else if (declp->b[0] == '_' && declp->b[1] == '_'
2868 && declp->b[2] == 'o' && declp->b[3] == 'p')
2870 /* ANSI. */
2871 /* type conversion operator. */
2872 tem = declp->b + 4;
2873 if (do_type (work, &tem, &type))
2875 string_clear (declp);
2876 string_append (declp, "operator ");
2877 string_appends (declp, &type);
2878 string_delete (&type);
2881 else if (declp->b[0] == '_' && declp->b[1] == '_'
2882 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2883 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2885 if (declp->b[4] == '\0')
2887 /* Operator. */
2888 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2890 if (strlen (optable[i].in) == 2
2891 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2893 string_clear (declp);
2894 string_append (declp, "operator");
2895 string_append (declp, optable[i].out);
2896 break;
2900 else
2902 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2904 /* Assignment. */
2905 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2907 if (strlen (optable[i].in) == 3
2908 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2910 string_clear (declp);
2911 string_append (declp, "operator");
2912 string_append (declp, optable[i].out);
2913 break;
2921 /* a mini string-handling package */
2923 static void
2924 string_need (s, n)
2925 string *s;
2926 int n;
2928 int tem;
2930 if (s->b == NULL)
2932 if (n < 32)
2934 n = 32;
2936 s->p = s->b = xmalloc (n);
2937 s->e = s->b + n;
2939 else if (s->e - s->p < n)
2941 tem = s->p - s->b;
2942 n += tem;
2943 n *= 2;
2944 s->b = xrealloc (s->b, n);
2945 s->p = s->b + tem;
2946 s->e = s->b + n;
2950 static void
2951 string_delete (s)
2952 string *s;
2954 if (s->b != NULL)
2956 free (s->b);
2957 s->b = s->e = s->p = NULL;
2961 static void
2962 string_init (s)
2963 string *s;
2965 s->b = s->p = s->e = NULL;
2968 static void
2969 string_clear (s)
2970 string *s;
2972 s->p = s->b;
2975 #if 0
2977 static int
2978 string_empty (s)
2979 string *s;
2981 return (s->b == s->p);
2984 #endif
2986 static void
2987 string_append (p, s)
2988 string *p;
2989 const char *s;
2991 int n;
2992 if (s == NULL || *s == '\0')
2993 return;
2994 n = strlen (s);
2995 string_need (p, n);
2996 memcpy (p->p, s, n);
2997 p->p += n;
3000 static void
3001 string_appends (p, s)
3002 string *p, *s;
3004 int n;
3006 if (s->b != s->p)
3008 n = s->p - s->b;
3009 string_need (p, n);
3010 memcpy (p->p, s->b, n);
3011 p->p += n;
3015 static void
3016 string_appendn (p, s, n)
3017 string *p;
3018 const char *s;
3019 int n;
3021 if (n != 0)
3023 string_need (p, n);
3024 memcpy (p->p, s, n);
3025 p->p += n;
3029 static void
3030 string_prepend (p, s)
3031 string *p;
3032 const char *s;
3034 if (s != NULL && *s != '\0')
3036 string_prependn (p, s, strlen (s));
3040 static void
3041 string_prepends (p, s)
3042 string *p, *s;
3044 if (s->b != s->p)
3046 string_prependn (p, s->b, s->p - s->b);
3050 static void
3051 string_prependn (p, s, n)
3052 string *p;
3053 const char *s;
3054 int n;
3056 char *q;
3058 if (n != 0)
3060 string_need (p, n);
3061 for (q = p->p - 1; q >= p->b; q--)
3063 q[n] = q[0];
3065 memcpy (p->b, s, n);
3066 p->p += n;
3070 /* To generate a standalone demangler program for testing purposes,
3071 just compile and link this file with -DMAIN and libiberty.a. When
3072 run, it demangles each command line arg, or each stdin string, and
3073 prints the result on stdout. */
3075 #ifdef MAIN
3077 #include "getopt.h"
3079 static char *program_name;
3080 static char *program_version = VERSION;
3081 static int flags = DMGL_PARAMS | DMGL_ANSI;
3083 static void demangle_it PARAMS ((char *));
3084 static void usage PARAMS ((FILE *, int));
3085 static void fatal PARAMS ((char *));
3087 static void
3088 demangle_it (mangled_name)
3089 char *mangled_name;
3091 char *result;
3093 result = cplus_demangle (mangled_name, flags);
3094 if (result == NULL)
3096 printf ("%s\n", mangled_name);
3098 else
3100 printf ("%s\n", result);
3101 free (result);
3105 static void
3106 usage (stream, status)
3107 FILE *stream;
3108 int status;
3110 fprintf (stream, "\
3111 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3112 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3113 [--help] [--version] [arg...]\n",
3114 program_name);
3115 exit (status);
3118 #define MBUF_SIZE 32767
3119 char mbuffer[MBUF_SIZE];
3121 /* Defined in the automatically-generated underscore.c. */
3122 extern int prepends_underscore;
3124 int strip_underscore = 0;
3126 static struct option long_options[] = {
3127 {"strip-underscores", no_argument, 0, '_'},
3128 {"format", required_argument, 0, 's'},
3129 {"help", no_argument, 0, 'h'},
3130 {"java", no_argument, 0, 'j'},
3131 {"no-strip-underscores", no_argument, 0, 'n'},
3132 {"version", no_argument, 0, 'v'},
3133 {0, no_argument, 0, 0}
3136 /* More 'friendly' abort that prints the line and file.
3137 config.h can #define abort fancy_abort if you like that sort of thing. */
3139 void
3140 fancy_abort ()
3142 fatal ("Internal gcc abort.");
3146 main (argc, argv)
3147 int argc;
3148 char **argv;
3150 char *result;
3151 int c;
3153 program_name = argv[0];
3155 strip_underscore = prepends_underscore;
3157 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3159 switch (c)
3161 case '?':
3162 usage (stderr, 1);
3163 break;
3164 case 'h':
3165 usage (stdout, 0);
3166 case 'n':
3167 strip_underscore = 0;
3168 break;
3169 case 'v':
3170 printf ("GNU %s version %s\n", program_name, program_version);
3171 exit (0);
3172 case '_':
3173 strip_underscore = 1;
3174 break;
3175 case 'j':
3176 flags |= DMGL_JAVA;
3177 break;
3178 case 's':
3179 if (strcmp (optarg, "gnu") == 0)
3181 current_demangling_style = gnu_demangling;
3183 else if (strcmp (optarg, "lucid") == 0)
3185 current_demangling_style = lucid_demangling;
3187 else if (strcmp (optarg, "arm") == 0)
3189 current_demangling_style = arm_demangling;
3191 else
3193 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3194 program_name, optarg);
3195 exit (1);
3197 break;
3201 if (optind < argc)
3203 for ( ; optind < argc; optind++)
3205 demangle_it (argv[optind]);
3208 else
3210 for (;;)
3212 int i = 0;
3213 c = getchar ();
3214 /* Try to read a label. */
3215 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3217 if (i >= MBUF_SIZE-1)
3218 break;
3219 mbuffer[i++] = c;
3220 c = getchar ();
3222 if (i > 0)
3224 int skip_first = 0;
3226 if (mbuffer[0] == '.')
3227 ++skip_first;
3228 if (strip_underscore && mbuffer[skip_first] == '_')
3229 ++skip_first;
3231 if (skip_first > i)
3232 skip_first = i;
3234 mbuffer[i] = 0;
3236 result = cplus_demangle (mbuffer + skip_first, flags);
3237 if (result)
3239 if (mbuffer[0] == '.')
3240 putc ('.', stdout);
3241 fputs (result, stdout);
3242 free (result);
3244 else
3245 fputs (mbuffer, stdout);
3247 fflush (stdout);
3249 if (c == EOF)
3250 break;
3251 putchar (c);
3255 exit (0);
3258 static void
3259 fatal (str)
3260 char *str;
3262 fprintf (stderr, "%s: %s\n", program_name, str);
3263 exit (1);
3266 char * malloc ();
3267 char * realloc ();
3269 char *
3270 xmalloc (size)
3271 unsigned size;
3273 register char *value = (char *) malloc (size);
3274 if (value == 0)
3275 fatal ("virtual memory exhausted");
3276 return value;
3279 char *
3280 xrealloc (ptr, size)
3281 char *ptr;
3282 unsigned size;
3284 register char *value = (char *) realloc (ptr, size);
3285 if (value == 0)
3286 fatal ("virtual memory exhausted");
3287 return value;
3289 #endif /* main */