1 /* Demangler for GNU C++
2 Copyright 1989, 1991 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 program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* This is for g++ 1.95.03 (November 13 version). */
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
28 /* GDB-specific, FIXME. */
35 #if !defined (GNU_DEMANGLING) && !defined (ARM_DEMANGLING)
36 # define GNU_DEMANGLING 1
39 /* This is '$' on systems where the assembler can deal with that.
40 Where the assembler can't, it's '.' (but on many systems '.' is
41 used for other things). */
43 #if !defined (CPLUS_MARKER)
44 #define CPLUS_MARKER '$'
51 /* Stuff that is shared between sub-routines.
52 * Using a shared structure allows cplus_demangle to be reentrant. */
62 int static_type
; /* A static member function */
63 int const_type
; /* A const member function */
66 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
67 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
69 static const struct optable
75 "nw", " new", DMGL_ANSI
, /* new (1.92, ansi) */
76 "dl", " delete", DMGL_ANSI
, /* new (1.92, ansi) */
77 "new", " new", 0, /* old (1.91, and 1.x) */
78 "delete", " delete", 0, /* old (1.91, and 1.x) */
79 "as", "=", DMGL_ANSI
, /* ansi */
80 "ne", "!=", DMGL_ANSI
, /* old, ansi */
81 "eq", "==", DMGL_ANSI
, /* old, ansi */
82 "ge", ">=", DMGL_ANSI
, /* old, ansi */
83 "gt", ">", DMGL_ANSI
, /* old, ansi */
84 "le", "<=", DMGL_ANSI
, /* old, ansi */
85 "lt", "<", DMGL_ANSI
, /* old, ansi */
86 "plus", "+", 0, /* old */
87 "pl", "+", DMGL_ANSI
, /* ansi */
88 "apl", "+=", DMGL_ANSI
, /* ansi */
89 "minus", "-", 0, /* old */
90 "mi", "-", DMGL_ANSI
, /* ansi */
91 "ami", "-=", DMGL_ANSI
, /* ansi */
92 "mult", "*", 0, /* old */
93 "ml", "*", DMGL_ANSI
, /* ansi */
95 "amu", "*=", DMGL_ANSI
, /* ansi */
97 "aml", "*=", DMGL_ANSI
, /* ansi */
99 "convert", "+", 0, /* old (unary +) */
100 "negate", "-", 0, /* old (unary -) */
101 "trunc_mod", "%", 0, /* old */
102 "md", "%", DMGL_ANSI
, /* ansi */
103 "amd", "%=", DMGL_ANSI
, /* ansi */
104 "trunc_div", "/", 0, /* old */
105 "dv", "/", DMGL_ANSI
, /* ansi */
106 "adv", "/=", DMGL_ANSI
, /* ansi */
107 "truth_andif", "&&", 0, /* old */
108 "aa", "&&", DMGL_ANSI
, /* ansi */
109 "truth_orif", "||", 0, /* old */
110 "oo", "||", DMGL_ANSI
, /* ansi */
111 "truth_not", "!", 0, /* old */
112 "nt", "!", DMGL_ANSI
, /* ansi */
113 "postincrement","++", 0, /* old */
114 "pp", "++", DMGL_ANSI
, /* ansi */
115 "postdecrement","--", 0, /* old */
116 "mm", "--", DMGL_ANSI
, /* ansi */
117 "bit_ior", "|", 0, /* old */
118 "or", "|", DMGL_ANSI
, /* ansi */
119 "aor", "|=", DMGL_ANSI
, /* ansi */
120 "bit_xor", "^", 0, /* old */
121 "er", "^", DMGL_ANSI
, /* ansi */
122 "aer", "^=", DMGL_ANSI
, /* ansi */
123 "bit_and", "&", 0, /* old */
124 "ad", "&", DMGL_ANSI
, /* ansi */
125 "aad", "&=", DMGL_ANSI
, /* ansi */
126 "bit_not", "~", 0, /* old */
127 "co", "~", DMGL_ANSI
, /* ansi */
128 "call", "()", 0, /* old */
129 "cl", "()", DMGL_ANSI
, /* ansi */
130 "alshift", "<<", 0, /* old */
131 "ls", "<<", DMGL_ANSI
, /* ansi */
132 "als", "<<=", DMGL_ANSI
, /* ansi */
133 "arshift", ">>", 0, /* old */
134 "rs", ">>", DMGL_ANSI
, /* ansi */
135 "ars", ">>=", DMGL_ANSI
, /* ansi */
136 "component", "->", 0, /* old */
137 #ifdef LUCID_DEMANGLING
138 "pt", "->", DMGL_ANSI
, /* ansi; Lucid C++ form */
140 "rf", "->", DMGL_ANSI
, /* ansi */
142 "indirect", "*", 0, /* old */
143 "method_call", "->()", 0, /* old */
144 "addr", "&", 0, /* old (unary &) */
145 "array", "[]", 0, /* old */
146 "vc", "[]", DMGL_ANSI
, /* ansi */
147 "compound", ", ", 0, /* old */
148 "cm", ", ", DMGL_ANSI
, /* ansi */
149 "cond", "?:", 0, /* old */
150 "cn", "?:", DMGL_ANSI
, /* psuedo-ansi */
151 "max", ">?", 0, /* old */
152 "mx", ">?", DMGL_ANSI
, /* psuedo-ansi */
153 "min", "<?", 0, /* old */
154 "mn", "<?", DMGL_ANSI
, /* psuedo-ansi */
155 "nop", "", 0, /* old (for operator=) */
156 "rm", "->*", DMGL_ANSI
, /* ansi */
160 typedef struct string
/* Beware: these aren't required to be */
161 { /* '\0' terminated. */
162 char *b
; /* pointer to start of string */
163 char *p
; /* pointer after last character */
164 char *e
; /* pointer after end of allocated space */
167 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
168 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
169 string_prepend(str, " ");}
170 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
171 string_append(str, " ");}
173 /* Prototypes for local functions */
176 mop_up
PARAMS ((string
*, struct work_stuff
*, int));
180 demangle_method_args
PARAMS ((string
*, const char **, struct work_stuff
*));
184 demangle_template
PARAMS ((string
*declp
, const char **, struct work_stuff
*));
187 demangle_qualified
PARAMS ((string
*, const char **, struct work_stuff
*));
190 demangle_class
PARAMS ((string
*, const char **, struct work_stuff
*));
193 demangle_fund_type
PARAMS ((const char **, string
*, struct work_stuff
*));
196 demangle_signature
PARAMS ((string
*, const char **, struct work_stuff
*));
199 demangle_prefix
PARAMS ((string
*, const char **, struct work_stuff
*));
202 gnu_special
PARAMS ((string
*, const char **, struct work_stuff
*));
205 string_need
PARAMS ((string
*, int));
208 string_delete
PARAMS ((string
*));
211 string_init
PARAMS ((string
*));
214 string_clear
PARAMS ((string
*));
218 string_empty
PARAMS ((string
*));
222 string_append
PARAMS ((string
*, const char *));
225 string_appends
PARAMS ((string
*, string
*));
228 string_appendn
PARAMS ((string
*, const char *, int));
231 string_prepend
PARAMS ((string
*, const char *));
234 string_prependn
PARAMS ((string
*, const char *, int));
237 get_count
PARAMS ((const char **, int *));
240 consume_count
PARAMS ((const char **));
243 demangle_args
PARAMS ((string
*, const char **, struct work_stuff
*));
246 do_type
PARAMS ((const char **, string
*, struct work_stuff
*));
249 do_arg
PARAMS ((const char **, string
*, struct work_stuff
*));
252 demangle_function_name
PARAMS ((string
*, const char **, struct work_stuff
*,
256 remember_type
PARAMS ((const char *, int, struct work_stuff
*));
260 string_prepends
PARAMS ((string
*, string
*));
263 /* Translate count to integer, consuming tokens in the process.
264 Conversion terminates on the first non-digit character. */
275 count
+= **type
- '0';
277 } while (isdigit (**type
));
281 /* Takes operator name as e.g. "++" and returns mangled
282 operator name (e.g. "postincrement_expr"), or NULL if not found.
284 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
285 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
288 cplus_mangle_opname (opname
, options
)
295 len
= strlen (opname
);
296 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
298 if (strlen (optable
[i
].out
) == len
299 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
300 && memcmp (optable
[i
].out
, opname
, len
) == 0)
301 return ((char *)optable
[i
].in
);
306 /* char *cplus_demangle (const char *name, int options)
308 If NAME is a mangled function name produced by GNU C++, then
309 a pointer to a malloced string giving a C++ representation
310 of the name will be returned; otherwise NULL will be returned.
311 It is the caller's responsibility to free the string which
314 The OPTIONS arg may contain one or more of the following bits:
316 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
318 DMGL_PARAMS Function parameters are included.
322 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
323 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
324 cplus_demangle ("foo__1Ai", 0) => "A::foo"
326 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
327 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
328 cplus_demangle ("foo__1Afe", 0) => "A::foo"
330 Note that any leading underscores, or other such characters prepended by
331 the compilation system, are presumed to have already been stripped from
335 cplus_demangle (mangled
, options
)
341 struct work_stuff work
[1];
342 char *demangled
= NULL
;
344 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
346 (void) memset ((char *) work
, 0, sizeof (work
));
347 work
-> options
= options
;
350 success
= demangle_prefix (&decl
, &mangled
, work
);
351 if (success
&& (*mangled
!= '\0'))
353 success
= demangle_signature (&decl
, &mangled
, work
);
355 demangled
= mop_up (&decl
, work
, success
);
361 mop_up (declp
, work
, success
)
363 struct work_stuff
*work
;
367 char *demangled
= NULL
;
369 /* Discard the remembered types, if any. */
371 for (i
= 0; i
< work
-> ntypes
; i
++)
373 if (work
-> typevec
[i
] != NULL
)
375 free (work
-> typevec
[i
]);
378 if (work
-> typevec
!= NULL
)
380 free ((char *) work
-> typevec
);
383 /* If demangling was successful, ensure that the demangled string is null
384 terminated and return it. Otherwise, free the demangling decl. */
388 string_delete (declp
);
392 string_appendn (declp
, "", 1);
393 demangled
= declp
-> b
;
402 demangle_signature -- demangle the signature part of a mangled name
407 demangle_signature (string *declp, const char **mangled,
408 struct work_stuff *work);
412 Consume and demangle the signature portion of the mangled name.
414 DECLP is the string where demangled output is being built. At
415 entry it contains the demangled root name from the mangled name
416 prefix. I.E. either a demangled operator name or the root function
417 name. In some special cases, it may contain nothing.
419 *MANGLED points to the current unconsumed location in the mangled
420 name. As tokens are consumed and demangling is performed, the
421 pointer is updated to continuously point at the next token to
424 Demangling GNU style mangled names is nasty because there is no
425 explicit token that marks the start of the outermost function
430 demangle_signature (declp
, mangled
, work
)
432 const char **mangled
;
433 struct work_stuff
*work
;
437 #ifdef GNU_DEMANGLING
441 const char *premangle
;
445 premangle
= *mangled
;
448 while (success
&& (**mangled
!= '\0'))
453 success
= demangle_qualified (declp
, mangled
, work
);
454 #ifdef GNU_DEMANGLING
460 /* Static member function */
462 work
-> static_type
= 1;
466 /* a const member function */
468 work
-> const_type
= 1;
471 case '0': case '1': case '2': case '3': case '4':
472 case '5': case '6': case '7': case '8': case '9':
473 success
= demangle_class (declp
, mangled
, work
);
477 remember_type (premangle
, *mangled
- premangle
, work
);
480 #ifdef GNU_DEMANGLING
487 /* ARM style demangling includes a specific 'F' character after
488 the class name. For GNU style, it is just implied. So we can
489 safely just consume any 'F' at this point and be compatible
490 with either style. */
493 success
= demangle_args (declp
, mangled
, work
);
498 success
= demangle_template (declp
, mangled
, work
);
502 /* At the outermost level, we cannot have a return type specified,
503 so if we run into another '_' at this point we are dealing with
504 a mangled name that is either bogus, or has been mangled by
505 some algorithm we don't know how to deal with. So just
506 reject the entire demangling. */
511 #ifdef GNU_DEMANGLING
512 /* Assume we have stumbled onto the first outermost function
513 argument token, and start processing args. */
515 success
= demangle_args (declp
, mangled
, work
);
517 /* Non-GNU demanglers use a specific token to mark the start
518 of the outermost function argument tokens. Typically 'F',
519 for ARM-demangling, for example. So if we find something
520 we are not prepared for, it must be an error. */
525 #ifdef GNU_DEMANGLING
526 if (success
&& expect_func
)
529 success
= demangle_args (declp
, mangled
, work
);
533 if (success
&& !func_done
)
535 #ifdef GNU_DEMANGLING
536 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
537 bar__3fooi is 'foo::bar(int)'. We get here when we find the
538 first case, and need to ensure that the '(void)' gets added to
539 the current declp. Note that with ARM_DEMANGLING, the first
540 case represents the name of a static data member 'foo::bar',
541 which is in the current declp, so we leave it alone. */
542 success
= demangle_args (declp
, mangled
, work
);
545 if (success
&& work
-> static_type
&& PRINT_ARG_TYPES
)
547 string_append (declp
, " static");
549 if (success
&& work
-> const_type
&& PRINT_ARG_TYPES
)
551 string_append (declp
, " const");
559 demangle_method_args (declp
, mangled
, work
)
561 const char **mangled
;
562 struct work_stuff
*work
;
566 if (work
-> static_type
)
568 string_append (declp
, *mangled
+ 1);
569 *mangled
+= strlen (*mangled
);
574 success
= demangle_args (declp
, mangled
, work
);
582 demangle_template (declp
, mangled
, work
)
584 const char **mangled
;
585 struct work_stuff
*work
;
602 string_init (&tname
);
603 string_init (&trawname
);
604 /* get template name */
605 if (!get_count (mangled
, &r
))
609 string_appendn (&tname
, *mangled
, r
);
610 string_appendn (&trawname
, *mangled
, r
);
611 string_appendn (&trawname
, "", 1);
613 string_append (&tname
, "<");
614 /* get size of template parameter list */
615 if (!get_count (mangled
, &r
))
619 for (i
= 0; i
< r
; i
++)
623 string_append (&tname
, ", ");
625 /* Z for type parameters */
626 if (**mangled
== 'Z')
629 success
= do_type (mangled
, &temp
, work
);
630 string_appendn (&temp
, "", 1);
633 string_append (&tname
, temp
.b
);
635 string_delete(&temp
);
643 /* otherwise, value parameter */
649 success
= do_type (mangled
, &temp
, work
);
650 string_appendn (&temp
, "", 1);
653 string_append (&tname
, temp
.b
);
655 string_delete(&temp
);
660 string_append (&tname
, "=");
661 while (*old_p
&& !done
)
667 done
= is_pointer
= 1;
669 case 'C': /* const */
670 case 'S': /* explicitly signed [char] */
671 case 'U': /* unsigned */
672 case 'V': /* volatile */
673 case 'F': /* function */
674 case 'M': /* member function */
678 case 'Q': /* repetition of following */
679 case 'T': /* remembered type */
685 case 'x': /* long long */
688 case 's': /* short */
690 done
= is_integral
= 1;
692 case 'r': /* long double */
693 case 'd': /* double */
694 case 'f': /* float */
703 if (**mangled
== 'm')
705 string_appendn (&tname
, "-", 1);
708 while (isdigit (**mangled
))
710 string_appendn (&tname
, *mangled
, 1);
716 if (**mangled
== 'm')
718 string_appendn (&tname
, "-", 1);
721 while (isdigit (**mangled
))
723 string_appendn (&tname
, *mangled
, 1);
726 if (**mangled
== '.') /* fraction */
728 string_appendn (&tname
, ".", 1);
730 while (isdigit (**mangled
))
732 string_appendn (&tname
, *mangled
, 1);
736 if (**mangled
== 'e') /* exponent */
738 string_appendn (&tname
, "e", 1);
740 while (isdigit (**mangled
))
742 string_appendn (&tname
, *mangled
, 1);
749 if (!get_count (mangled
, &symbol_len
))
754 string_appendn (&tname
, *mangled
, symbol_len
);
755 *mangled
+= symbol_len
;
760 string_append (&tname
, ">::");
761 if (work
-> destructor
)
763 string_append (&tname
, "~");
765 if (work
-> constructor
|| work
-> destructor
)
767 string_append (&tname
, trawname
.b
);
769 string_delete(&trawname
);
773 string_delete(&tname
);
777 string_prepend (declp
, tname
.b
);
778 string_delete (&tname
);
780 if (work
-> static_type
)
782 string_append (declp
, *mangled
+ 1);
783 *mangled
+= strlen (*mangled
);
788 success
= demangle_args (declp
, mangled
, work
);
798 demangle_class -- demangle a mangled class sequence
803 demangle_class (string *declp, const char **mangled,
804 struct work_stuff *work)
808 DECLP points to the buffer into which demangling is being done.
810 *MANGLED points to the current token to be demangled. On input,
811 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
812 On exit, it points to the next token after the mangled class on
813 success, or the first unconsumed token on failure.
815 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
816 we are demangling a constructor or destructor. In this case
817 we prepend "class::class" or "class::~class" to DECLP.
819 Otherwise, we prepend "class::" to the current DECLP.
821 Reset the constructor/destructor flags once they have been
822 "consumed". This allows demangle_class to be called later during
823 the same demangling, to do normal class demangling.
825 Returns 1 if demangling is successful, 0 otherwise.
830 demangle_class (declp
, mangled
, work
)
832 const char **mangled
;
833 struct work_stuff
*work
;
838 n
= consume_count (mangled
);
839 if (strlen (*mangled
) >= n
)
841 if (work
-> constructor
|| work
-> destructor
)
843 string_prependn (declp
, *mangled
, n
);
844 if (work
-> destructor
)
846 string_prepend (declp
, "~");
848 work
-> constructor
= work
-> destructor
= 0;
850 string_prepend (declp
, "::");
851 string_prependn (declp
, *mangled
, n
);
862 demangle_prefix -- consume the mangled name prefix and find signature
867 demangle_prefix (string *declp, const char **mangled,
868 struct work_stuff *work)
872 Consume and demangle the prefix of the mangled name.
874 DECLP points to the string buffer into which demangled output is
875 placed. On entry, the buffer is empty. On exit it contains
876 the root function name, the demangled operator name, or in some
877 special cases either nothing or the completely demangled result.
879 MANGLED points to the current pointer into the mangled name. As each
880 token of the mangled name is consumed, it is updated. Upon entry
881 the current mangled name pointer points to the first character of
882 the mangled name. Upon exit, it should point to the first character
883 of the signature if demangling was successful, or to the first
884 unconsumed character if demangling of the prefix was unsuccessful.
886 Returns 1 on success, 0 otherwise.
890 demangle_prefix (declp
, mangled
, work
)
892 const char **mangled
;
893 struct work_stuff
*work
;
898 if ((scan
= strstr (*mangled
, "__")) == NULL
)
900 success
= gnu_special (declp
, mangled
, work
);
902 else if (work
-> static_type
)
904 if (!isdigit (scan
[0]) && (scan
[0] != 't'))
909 else if ((scan
== *mangled
) && (isdigit (scan
[2]) || (scan
[2] == 'Q')))
911 /* A GNU style constructor starts with "__<digit>" or "__Q". */
912 work
-> constructor
= 1;
915 else if ((scan
== *mangled
) && !isdigit (scan
[2]) && (scan
[2] != 't'))
917 /* Mangled name starts with "__". Skip over any leading '_' characters,
918 then find the next "__" that separates the prefix from the signature.
924 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
926 /* No separator (I.E. "__not_mangled"), or empty signature
927 (I.E. "__not_mangled_either__") */
932 demangle_function_name (declp
, mangled
, work
, scan
);
935 else if (*(scan
+ 2) != '\0')
937 /* Mangled name does not start with "__" but does have one somewhere
938 in there with non empty stuff after it. Looks like a global
940 demangle_function_name (declp
, mangled
, work
, scan
);
944 /* Doesn't look like a mangled name */
954 gnu_special -- special handling of gnu mangled strings
959 gnu_special (string *declp, const char **mangled,
960 struct work_stuff *work)
965 Process some special GNU style mangling forms that don't fit
966 the normal pattern. For example:
968 _$_3foo (destructor for class foo)
969 _vt$foo (virtual table)
970 _3foo$varname (static data member)
974 gnu_special (declp
, mangled
, work
)
976 const char **mangled
;
977 struct work_stuff
*work
;
983 if ((*mangled
)[0] == '_'
984 && (*mangled
)[1] == CPLUS_MARKER
985 && (*mangled
)[2] == '_')
987 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
989 work
-> destructor
= 1;
991 else if ((*mangled
)[0] == '_'
992 && (*mangled
)[1] == 'v'
993 && (*mangled
)[2] == 't'
994 && (*mangled
)[3] == CPLUS_MARKER
)
996 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
997 and create the decl. Note that we consume the entire mangled
998 input string, which means that demangle_signature has no work
1001 n
= strlen (*mangled
);
1002 string_appendn (declp
, *mangled
, n
);
1003 string_append (declp
, " virtual table");
1006 else if ((*mangled
)[0] == '_'
1007 && isdigit ((*mangled
)[1])
1008 && (p
= strchr (*mangled
, CPLUS_MARKER
)) != NULL
)
1010 /* static data member, "_3foo$varname" for example */
1013 n
= consume_count (mangled
);
1014 string_appendn (declp
, *mangled
, n
);
1015 string_append (declp
, "::");
1017 string_appendn (declp
, p
, n
);
1027 /* Do a qualified name, such as "Q25Outer5Inner" for "Outer::Inner" */
1030 demangle_qualified (declp
, mangled
, work
)
1032 const char **mangled
;
1033 struct work_stuff
*work
;
1040 n
= (*mangled
)[1] - '0';
1041 if (n
>= 0 && n
<= 9)
1043 if ((*mangled
)[2] == '_')
1049 string_init (&class);
1052 success
= do_type (mangled
, &tmp
, work
);
1053 string_appends (&class, &tmp
);
1054 string_append (&class, "::");
1055 if (n
== 0 && (work
-> constructor
|| work
-> destructor
))
1057 if (work
-> destructor
)
1059 string_append (&class, "~");
1061 string_appends (&class, &tmp
);
1063 string_delete (&tmp
);
1065 work
-> constructor
= work
-> destructor
= 0;
1066 string_prependn (declp
, class.b
, class.p
- class.b
);
1067 string_delete (&class);
1076 get_count -- convert an ascii count to integer, consuming tokens
1081 get_count (const char **type, int *count)
1085 Return 0 if no conversion is performed, 1 if a string is converted.
1089 get_count (type
, count
)
1096 if (!isdigit (**type
))
1102 *count
= **type
- '0';
1104 if (isdigit (**type
))
1114 while (isdigit (*p
));
1125 /* result will be initialised here; it will be freed on failure */
1128 do_type (type
, result
, work
)
1131 struct work_stuff
*work
;
1137 const char *remembered_type
;
1141 string_init (&decl
);
1142 string_init (result
);
1146 while (success
&& !done
)
1151 /* A qualified name, such as "Outer::Inner". Note qualifier count
1152 is limited to a single digit (0-9 qualifiers). */
1154 n
= (*type
)[1] - '0';
1159 if ((*type
)[2] == '_') /* cfront style */
1166 do_type (type
, result
, work
);
1170 /* A pointer type */
1173 string_prepend (&decl
, "*");
1176 /* A reference type */
1179 string_prepend (&decl
, "&");
1182 /* A back reference to a previously seen type */
1185 if (!get_count (type
, &n
) || n
>= work
-> ntypes
)
1191 remembered_type
= work
-> typevec
[n
];
1192 type
= &remembered_type
;
1199 if (!STRING_EMPTY (&decl
) && decl
.b
[0] == '*')
1201 string_prepend (&decl
, "(");
1202 string_append (&decl
, ")");
1204 /* After picking off the function args, we expect to either find the
1205 function return type (preceded by an '_') or the end of the
1207 if (!demangle_args (&decl
, type
, work
)
1208 || (**type
!= '_' && **type
!= '\0'))
1212 if (success
&& (**type
== '_'))
1224 member
= **type
== 'M';
1226 if (!isdigit (**type
))
1231 n
= consume_count (type
);
1232 if (strlen (*type
) < n
)
1237 string_append (&decl
, ")");
1238 string_prepend (&decl
, "::");
1239 string_prependn (&decl
, *type
, n
);
1240 string_prepend (&decl
, "(");
1254 if (*(*type
)++ != 'F')
1260 if ((member
&& !demangle_args (&decl
, type
, work
))
1267 if (! PRINT_ANSI_QUALIFIERS
)
1273 APPEND_BLANK (&decl
);
1274 string_append (&decl
, "const");
1278 APPEND_BLANK (&decl
);
1279 string_append (&decl
, "volatile");
1285 if ((*type
)[1] == 'P')
1288 if (PRINT_ANSI_QUALIFIERS
)
1290 if (!STRING_EMPTY (&decl
))
1292 string_prepend (&decl
, " ");
1294 string_prepend (&decl
, "const");
1306 success
= demangle_fund_type (type
, result
, work
);
1310 if (!STRING_EMPTY (&decl
))
1312 string_append (result
, " ");
1313 string_appends (result
, &decl
);
1318 string_delete (result
);
1320 string_delete (&decl
);
1324 /* Given a pointer to a type string that represents a fundamental type
1325 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
1326 string in which the demangled output is being built in RESULT, and
1327 the WORK structure, decode the types and add them to the result.
1332 "Sl" => "signed long"
1333 "CUs" => "const unsigned short"
1338 demangle_fund_type (type
, result
, work
)
1341 struct work_stuff
*work
;
1347 /* First pick off any type qualifiers. There can be more than one. */
1355 if (PRINT_ANSI_QUALIFIERS
)
1357 APPEND_BLANK (result
);
1358 string_append (result
, "const");
1363 APPEND_BLANK (result
);
1364 string_append (result
, "unsigned");
1366 case 'S': /* signed char only */
1368 APPEND_BLANK (result
);
1369 string_append (result
, "signed");
1373 if (PRINT_ANSI_QUALIFIERS
)
1375 APPEND_BLANK (result
);
1376 string_append (result
, "volatile");
1385 /* Now pick off the fundamental type. There can be only one. */
1394 APPEND_BLANK (result
);
1395 string_append (result
, "void");
1399 APPEND_BLANK (result
);
1400 string_append (result
, "long long");
1404 APPEND_BLANK (result
);
1405 string_append (result
, "long");
1409 APPEND_BLANK (result
);
1410 string_append (result
, "int");
1414 APPEND_BLANK (result
);
1415 string_append (result
, "short");
1419 APPEND_BLANK (result
);
1420 string_append (result
, "char");
1424 APPEND_BLANK (result
);
1425 string_append (result
, "long double");
1429 APPEND_BLANK (result
);
1430 string_append (result
, "double");
1434 APPEND_BLANK (result
);
1435 string_append (result
, "float");
1439 if (!isdigit (**type
))
1445 /* An explicit type, such as "6mytype" or "7integer" */
1456 n
= consume_count (type
);
1457 if (strlen (*type
) < n
)
1462 APPEND_BLANK (result
);
1463 string_appendn (result
, *type
, n
);
1474 /* `result' will be initialized in do_type; it will be freed on failure */
1477 do_arg (type
, result
, work
)
1480 struct work_stuff
*work
;
1482 const char *start
= *type
;
1484 if (!do_type (type
, result
, work
))
1490 remember_type (start
, *type
- start
, work
);
1496 remember_type (start
, len
, work
)
1499 struct work_stuff
*work
;
1503 if (work
-> ntypes
>= work
-> typevec_size
)
1505 if (work
-> typevec_size
== 0)
1507 work
-> typevec_size
= 3;
1509 (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
1513 work
-> typevec_size
*= 2;
1515 (char **) xrealloc ((char *)work
-> typevec
,
1516 sizeof (char *) * work
-> typevec_size
);
1519 tem
= (char *) xmalloc (len
+ 1);
1520 memcpy (tem
, start
, len
);
1522 work
-> typevec
[work
-> ntypes
++] = tem
;
1525 /* Process the argument list part of the signature, after any class spec
1526 has been consumed, as well as the first 'F' character (if any). For
1529 "__als__3fooRT0" => process "RT0"
1530 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
1532 DECLP must be already initialised, usually non-empty. It won't be freed
1536 demangle_args (declp
, type
, work
)
1539 struct work_stuff
*work
;
1548 if (PRINT_ARG_TYPES
)
1550 string_append (declp
, "(");
1553 string_append (declp
, "void");
1557 while (**type
!= '_' && **type
!= '\0' && **type
!= 'e')
1559 if ((**type
== 'N') || (**type
== 'T'))
1561 temptype
= *(*type
)++;
1563 if (temptype
== 'N')
1565 if (!get_count (type
, &r
))
1574 if (!get_count (type
, &t
))
1578 #ifdef ARM_DEMANGLING
1581 if (t
>= work
-> ntypes
)
1587 tem
= work
-> typevec
[t
];
1588 if (need_comma
&& PRINT_ARG_TYPES
)
1590 string_append (declp
, ", ");
1592 if (!do_arg (&tem
, &arg
, work
))
1596 if (PRINT_ARG_TYPES
)
1598 string_appends (declp
, &arg
);
1600 string_delete (&arg
);
1606 if (need_comma
& PRINT_ARG_TYPES
)
1608 string_append (declp
, ", ");
1610 if (!do_arg (type
, &arg
, work
))
1614 if (PRINT_ARG_TYPES
)
1616 string_appends (declp
, &arg
);
1618 string_delete (&arg
);
1626 if (PRINT_ARG_TYPES
)
1630 string_append (declp
, ",");
1632 string_append (declp
, "...");
1636 if (PRINT_ARG_TYPES
)
1638 string_append (declp
, ")");
1644 demangle_function_name (declp
, mangled
, work
, scan
)
1646 const char **mangled
;
1647 struct work_stuff
*work
;
1655 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
1656 string_need (declp
, 1);
1657 *(declp
-> p
) = '\0';
1659 /* Consume the function name, including the "__" separating the name
1660 from the signature. We are guaranteed that SCAN points to the
1663 (*mangled
) = scan
+ 2;
1665 #ifdef ARM_DEMANGLING
1667 /* See if we have an ARM style constructor or destructor operator.
1668 If so, then just record it, clear the decl, and return.
1669 We can't build the actual constructor/destructor decl until later,
1670 when we recover the class name from the signature. */
1672 if (strcmp (declp
-> b
, "__ct") == 0)
1674 work
-> constructor
= 1;
1675 string_clear (declp
);
1678 else if (strcmp (declp
-> b
, "__dt") == 0)
1680 work
-> destructor
= 1;
1681 string_clear (declp
);
1687 if (declp
->p
- declp
->b
>= 3
1688 && declp
->b
[0] == 'o'
1689 && declp
->b
[1] == 'p'
1690 && declp
->b
[2] == CPLUS_MARKER
)
1692 /* see if it's an assignment expression */
1693 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
1694 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
1696 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1698 len
= declp
->p
- declp
->b
- 10;
1699 if (strlen (optable
[i
].in
) == len
1700 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
1702 string_clear (declp
);
1703 string_append (declp
, "operator");
1704 string_append (declp
, optable
[i
].out
);
1705 string_append (declp
, "=");
1712 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1714 int len
= declp
->p
- declp
->b
- 3;
1715 if (strlen (optable
[i
].in
) == len
1716 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
1718 string_clear (declp
);
1719 string_append (declp
, "operator");
1720 string_append (declp
, optable
[i
].out
);
1726 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type$", 5) == 0)
1728 /* type conversion operator */
1730 if (do_type (&tem
, &type
, work
))
1732 string_clear (declp
);
1733 string_append (declp
, "operator ");
1734 string_appends (declp
, &type
);
1735 string_delete (&type
);
1738 else if (declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
1741 /* type conversion operator. */
1743 if (do_type (&tem
, &type
, work
))
1745 string_clear (declp
);
1746 string_append (declp
, "operator ");
1747 string_appends (declp
, &type
);
1748 string_delete (&type
);
1751 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
1752 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
1753 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
1755 if (declp
->b
[4] == '\0')
1758 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1760 if (strlen (optable
[i
].in
) == 2
1761 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
1763 string_clear (declp
);
1764 string_append (declp
, "operator");
1765 string_append (declp
, optable
[i
].out
);
1772 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
1775 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1777 if (strlen (optable
[i
].in
) == 3
1778 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
1780 string_clear (declp
);
1781 string_append (declp
, "operator");
1782 string_append (declp
, optable
[i
].out
);
1791 /* a mini string-handling package */
1806 s
->p
= s
->b
= (char *) xmalloc (n
);
1809 else if (s
->e
- s
->p
< n
)
1814 s
->b
= (char *) xrealloc (s
->b
, n
);
1827 s
->b
= s
->e
= s
->p
= NULL
;
1835 s
->b
= s
->p
= s
->e
= NULL
;
1851 return (s
->b
== s
->p
);
1857 string_append (p
, s
)
1862 if (s
== NULL
|| *s
== '\0')
1866 memcpy (p
->p
, s
, n
);
1871 string_appends (p
, s
)
1880 memcpy (p
->p
, s
->b
, n
);
1886 string_appendn (p
, s
, n
)
1894 memcpy (p
->p
, s
, n
);
1900 string_prepend (p
, s
)
1904 if (s
!= NULL
&& *s
!= '\0')
1906 string_prependn (p
, s
, strlen (s
));
1913 string_prepends (p
, s
)
1918 string_prependn (p
, s
->b
, s
->p
- s
->b
);
1925 string_prependn (p
, s
, n
)
1935 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
1939 memcpy (p
->b
, s
, n
);
1944 /* To generate a standalone demangler program for testing purposes, just
1945 compile and link this file with -DMAIN. When run, it demangles each
1946 command line arg, or each stdin string, and prints the result on stdout. */
1951 demangle_it (mangled_name
)
1956 result
= cplus_demangle (mangled_name
, DMGL_PARAMS
| DMGL_ANSI
);
1959 printf ("%s\n", mangled_name
);
1963 printf ("%s\n", result
);
1974 if ((newmem
= malloc ((int) size
)) == NULL
)
1976 fprintf (stderr
, "\nCan't allocate %u bytes\n", size
);
1983 xrealloc (oldmem
, size
)
1989 if ((newmem
= realloc ((char *) oldmem
, (int) size
)) == NULL
)
1991 fprintf (stderr
, "\nCan't reallocate %u bytes\n", size
);
2001 char mangled_name
[128];
2010 demangle_it (*argv
);
2015 while (gets (mangled_name
))
2017 demangle_it (mangled_name
);
This page took 0.070406 seconds and 5 git commands to generate.