1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 98, 1999 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
5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 Libiberty is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with libiberty; see the file COPYING.LIB. If
20 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
25 This file imports xmalloc and xrealloc, which are like malloc and
26 realloc except that they generate a fatal error if there is no
29 /* This file lives in both GCC and libiberty. When making changes, please
30 try not to break either. */
37 #include <sys/types.h>
49 #undef CURRENT_DEMANGLING_STYLE
50 #define CURRENT_DEMANGLING_STYLE work->options
52 #include "libiberty.h"
54 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
56 /* A value at least one greater than the maximum number of characters
57 that will be output when using the `%d' format with `printf'. */
58 #define INTBUF_SIZE 32
60 extern void fancy_abort
PARAMS ((void)) ATTRIBUTE_NORETURN
;
62 static const char *mystrstr
PARAMS ((const char *, const char *));
68 register const char *p
= s1
;
69 register int len
= strlen (s2
);
71 for (; (p
= strchr (p
, *s2
)) != 0; p
++)
73 if (strncmp (p
, s2
, len
) == 0)
81 /* In order to allow a single demangler executable to demangle strings
82 using various common values of CPLUS_MARKER, as well as any specific
83 one set at compile time, we maintain a string containing all the
84 commonly used ones, and check to see if the marker we are looking for
85 is in that string. CPLUS_MARKER is usually '$' on systems where the
86 assembler can deal with that. Where the assembler can't, it's usually
87 '.' (but on many systems '.' is used for other things). We put the
88 current defined CPLUS_MARKER first (which defaults to '$'), followed
89 by the next most common value, followed by an explicit '$' in case
90 the value of CPLUS_MARKER is not '$'.
92 We could avoid this if we could just get g++ to tell us what the actual
93 cplus marker character is as part of the debug information, perhaps by
94 ensuring that it is the character that terminates the gcc<n>_compiled
95 marker symbol (FIXME). */
97 #if !defined (CPLUS_MARKER)
98 #define CPLUS_MARKER '$'
101 enum demangling_styles current_demangling_style
= gnu_demangling
;
103 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
105 static char char_str
[2] = { '\000', '\000' };
108 set_cplus_marker_for_demangling (ch
)
111 cplus_markers
[0] = ch
;
114 typedef struct string
/* Beware: these aren't required to be */
115 { /* '\0' terminated. */
116 char *b
; /* pointer to start of string */
117 char *p
; /* pointer after last character */
118 char *e
; /* pointer after end of allocated space */
121 /* Stuff that is shared between sub-routines.
122 Using a shared structure allows cplus_demangle to be reentrant. */
138 int static_type
; /* A static member function */
139 int temp_start
; /* index in demangled to start of template args */
140 int type_quals
; /* The type qualifiers. */
141 int dllimported
; /* Symbol imported from a PE DLL */
142 char **tmpl_argvec
; /* Template function arguments. */
143 int ntmpl_args
; /* The number of template function arguments. */
144 int forgetting_types
; /* Nonzero if we are not remembering the types
146 string
* previous_argument
; /* The last function argument demangled. */
147 int nrepeats
; /* The number of times to repeat the previous
151 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
152 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
154 static const struct optable
160 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
161 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
162 {"new", " new", 0}, /* old (1.91, and 1.x) */
163 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
164 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
165 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
166 {"as", "=", DMGL_ANSI
}, /* ansi */
167 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
168 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
169 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
170 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
171 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
172 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
173 {"plus", "+", 0}, /* old */
174 {"pl", "+", DMGL_ANSI
}, /* ansi */
175 {"apl", "+=", DMGL_ANSI
}, /* ansi */
176 {"minus", "-", 0}, /* old */
177 {"mi", "-", DMGL_ANSI
}, /* ansi */
178 {"ami", "-=", DMGL_ANSI
}, /* ansi */
179 {"mult", "*", 0}, /* old */
180 {"ml", "*", DMGL_ANSI
}, /* ansi */
181 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
182 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
183 {"convert", "+", 0}, /* old (unary +) */
184 {"negate", "-", 0}, /* old (unary -) */
185 {"trunc_mod", "%", 0}, /* old */
186 {"md", "%", DMGL_ANSI
}, /* ansi */
187 {"amd", "%=", DMGL_ANSI
}, /* ansi */
188 {"trunc_div", "/", 0}, /* old */
189 {"dv", "/", DMGL_ANSI
}, /* ansi */
190 {"adv", "/=", DMGL_ANSI
}, /* ansi */
191 {"truth_andif", "&&", 0}, /* old */
192 {"aa", "&&", DMGL_ANSI
}, /* ansi */
193 {"truth_orif", "||", 0}, /* old */
194 {"oo", "||", DMGL_ANSI
}, /* ansi */
195 {"truth_not", "!", 0}, /* old */
196 {"nt", "!", DMGL_ANSI
}, /* ansi */
197 {"postincrement","++", 0}, /* old */
198 {"pp", "++", DMGL_ANSI
}, /* ansi */
199 {"postdecrement","--", 0}, /* old */
200 {"mm", "--", DMGL_ANSI
}, /* ansi */
201 {"bit_ior", "|", 0}, /* old */
202 {"or", "|", DMGL_ANSI
}, /* ansi */
203 {"aor", "|=", DMGL_ANSI
}, /* ansi */
204 {"bit_xor", "^", 0}, /* old */
205 {"er", "^", DMGL_ANSI
}, /* ansi */
206 {"aer", "^=", DMGL_ANSI
}, /* ansi */
207 {"bit_and", "&", 0}, /* old */
208 {"ad", "&", DMGL_ANSI
}, /* ansi */
209 {"aad", "&=", DMGL_ANSI
}, /* ansi */
210 {"bit_not", "~", 0}, /* old */
211 {"co", "~", DMGL_ANSI
}, /* ansi */
212 {"call", "()", 0}, /* old */
213 {"cl", "()", DMGL_ANSI
}, /* ansi */
214 {"alshift", "<<", 0}, /* old */
215 {"ls", "<<", DMGL_ANSI
}, /* ansi */
216 {"als", "<<=", DMGL_ANSI
}, /* ansi */
217 {"arshift", ">>", 0}, /* old */
218 {"rs", ">>", DMGL_ANSI
}, /* ansi */
219 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
220 {"component", "->", 0}, /* old */
221 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
222 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
223 {"indirect", "*", 0}, /* old */
224 {"method_call", "->()", 0}, /* old */
225 {"addr", "&", 0}, /* old (unary &) */
226 {"array", "[]", 0}, /* old */
227 {"vc", "[]", DMGL_ANSI
}, /* ansi */
228 {"compound", ", ", 0}, /* old */
229 {"cm", ", ", DMGL_ANSI
}, /* ansi */
230 {"cond", "?:", 0}, /* old */
231 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
232 {"max", ">?", 0}, /* old */
233 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
234 {"min", "<?", 0}, /* old */
235 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
236 {"nop", "", 0}, /* old (for operator=) */
237 {"rm", "->*", DMGL_ANSI
}, /* ansi */
238 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
241 /* These values are used to indicate the various type varieties.
242 They are all non-zero so that they can be used as `success'
244 typedef enum type_kind_t
255 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
256 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
257 string_prepend(str, " ");}
258 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
259 string_append(str, " ");}
260 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
262 /* The scope separator appropriate for the language being demangled. */
264 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
266 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
267 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
269 /* Prototypes for local functions */
272 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
275 squangle_mop_up
PARAMS ((struct work_stuff
*));
279 demangle_method_args
PARAMS ((struct work_stuff
*, const char **, string
*));
283 internal_cplus_demangle
PARAMS ((struct work_stuff
*, const char *));
286 demangle_template_template_parm
PARAMS ((struct work_stuff
*work
,
287 const char **, string
*));
290 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*,
291 string
*, int, int));
294 arm_pt
PARAMS ((struct work_stuff
*, const char *, int, const char **,
298 demangle_class_name
PARAMS ((struct work_stuff
*, const char **, string
*));
301 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
305 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
308 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
311 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
314 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
317 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
320 arm_special
PARAMS ((const char **, string
*));
323 string_need
PARAMS ((string
*, int));
326 string_delete
PARAMS ((string
*));
329 string_init
PARAMS ((string
*));
332 string_clear
PARAMS ((string
*));
336 string_empty
PARAMS ((string
*));
340 string_append
PARAMS ((string
*, const char *));
343 string_appends
PARAMS ((string
*, string
*));
346 string_appendn
PARAMS ((string
*, const char *, int));
349 string_prepend
PARAMS ((string
*, const char *));
352 string_prependn
PARAMS ((string
*, const char *, int));
355 string_append_template_idx
PARAMS ((string
*, int));
358 get_count
PARAMS ((const char **, int *));
361 consume_count
PARAMS ((const char **));
364 consume_count_with_underscores
PARAMS ((const char**));
367 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
370 demangle_nested_args
PARAMS ((struct work_stuff
*, const char**, string
*));
373 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
376 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
379 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
383 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
386 remember_Btype
PARAMS ((struct work_stuff
*, const char *, int, int));
389 register_Btype
PARAMS ((struct work_stuff
*));
392 remember_Ktype
PARAMS ((struct work_stuff
*, const char *, int));
395 forget_types
PARAMS ((struct work_stuff
*));
398 forget_B_and_K_types
PARAMS ((struct work_stuff
*));
401 string_prepends
PARAMS ((string
*, string
*));
404 demangle_template_value_parm
PARAMS ((struct work_stuff
*, const char**,
405 string
*, type_kind_t
));
408 do_hpacc_template_const_value
PARAMS ((struct work_stuff
*, const char **, string
*));
411 do_hpacc_template_literal
PARAMS ((struct work_stuff
*, const char **, string
*));
414 snarf_numeric_literal
PARAMS ((const char **, string
*));
416 /* There is a TYPE_QUAL value for each type qualifier. They can be
417 combined by bitwise-or to form the complete set of qualifiers for a
420 #define TYPE_UNQUALIFIED 0x0
421 #define TYPE_QUAL_CONST 0x1
422 #define TYPE_QUAL_VOLATILE 0x2
423 #define TYPE_QUAL_RESTRICT 0x4
426 code_for_qualifier
PARAMS ((int));
429 qualifier_string
PARAMS ((int));
432 demangle_qualifier
PARAMS ((int));
435 demangle_expression
PARAMS ((struct work_stuff
*, const char **, string
*,
439 demangle_integral_value
PARAMS ((struct work_stuff
*, const char **,
443 demangle_real_value
PARAMS ((struct work_stuff
*, const char **, string
*));
446 demangle_arm_hp_template
PARAMS ((struct work_stuff
*, const char **, int,
450 recursively_demangle
PARAMS ((struct work_stuff
*, const char **, string
*,
453 /* Translate count to integer, consuming tokens in the process.
454 Conversion terminates on the first non-digit character.
456 Trying to consume something that isn't a count results in no
457 consumption of input and a return of -1.
459 Overflow consumes the rest of the digits, and returns -1. */
467 if (! isdigit ((unsigned char)**type
))
470 while (isdigit ((unsigned char)**type
))
474 /* Check for overflow.
475 We assume that count is represented using two's-complement;
476 no power of two is divisible by ten, so if an overflow occurs
477 when multiplying by ten, the result will not be a multiple of
479 if ((count
% 10) != 0)
481 while (isdigit ((unsigned char) **type
))
486 count
+= **type
- '0';
494 /* Like consume_count, but for counts that are preceded and followed
495 by '_' if they are greater than 10. Also, -1 is returned for
496 failure, since 0 can be a valid value. */
499 consume_count_with_underscores (mangled
)
500 const char **mangled
;
504 if (**mangled
== '_')
507 if (!isdigit ((unsigned char)**mangled
))
510 idx
= consume_count (mangled
);
511 if (**mangled
!= '_')
512 /* The trailing underscore was missing. */
519 if (**mangled
< '0' || **mangled
> '9')
522 idx
= **mangled
- '0';
529 /* C is the code for a type-qualifier. Return the TYPE_QUAL
530 corresponding to this qualifier. */
533 code_for_qualifier (c
)
539 return TYPE_QUAL_CONST
;
542 return TYPE_QUAL_VOLATILE
;
545 return TYPE_QUAL_RESTRICT
;
551 /* C was an invalid qualifier. */
555 /* Return the string corresponding to the qualifiers given by
559 qualifier_string (type_quals
)
564 case TYPE_UNQUALIFIED
:
567 case TYPE_QUAL_CONST
:
570 case TYPE_QUAL_VOLATILE
:
573 case TYPE_QUAL_RESTRICT
:
576 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
577 return "const volatile";
579 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
580 return "const __restrict";
582 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
583 return "volatile __restrict";
585 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
586 return "const volatile __restrict";
592 /* TYPE_QUALS was an invalid qualifier set. */
596 /* C is the code for a type-qualifier. Return the string
597 corresponding to this qualifier. This function should only be
598 called with a valid qualifier code. */
601 demangle_qualifier (c
)
604 return qualifier_string (code_for_qualifier (c
));
608 cplus_demangle_opname (opname
, result
, options
)
615 struct work_stuff work
[1];
618 len
= strlen(opname
);
621 memset ((char *) work
, 0, sizeof (work
));
622 work
->options
= options
;
624 if (opname
[0] == '_' && opname
[1] == '_'
625 && opname
[2] == 'o' && opname
[3] == 'p')
628 /* type conversion operator. */
630 if (do_type (work
, &tem
, &type
))
632 strcat (result
, "operator ");
633 strncat (result
, type
.b
, type
.p
- type
.b
);
634 string_delete (&type
);
638 else if (opname
[0] == '_' && opname
[1] == '_'
639 && opname
[2] >= 'a' && opname
[2] <= 'z'
640 && opname
[3] >= 'a' && opname
[3] <= 'z')
642 if (opname
[4] == '\0')
646 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
648 if (strlen (optable
[i
].in
) == 2
649 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
651 strcat (result
, "operator");
652 strcat (result
, optable
[i
].out
);
660 if (opname
[2] == 'a' && opname
[5] == '\0')
664 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
666 if (strlen (optable
[i
].in
) == 3
667 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
669 strcat (result
, "operator");
670 strcat (result
, optable
[i
].out
);
681 && strchr (cplus_markers
, opname
[2]) != NULL
)
683 /* see if it's an assignment expression */
684 if (len
>= 10 /* op$assign_ */
685 && memcmp (opname
+ 3, "assign_", 7) == 0)
688 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
691 if ((int) strlen (optable
[i
].in
) == len1
692 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
694 strcat (result
, "operator");
695 strcat (result
, optable
[i
].out
);
696 strcat (result
, "=");
705 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
708 if ((int) strlen (optable
[i
].in
) == len1
709 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
711 strcat (result
, "operator");
712 strcat (result
, optable
[i
].out
);
719 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
720 && strchr (cplus_markers
, opname
[4]) != NULL
)
722 /* type conversion operator */
724 if (do_type (work
, &tem
, &type
))
726 strcat (result
, "operator ");
727 strncat (result
, type
.b
, type
.p
- type
.b
);
728 string_delete (&type
);
732 squangle_mop_up (work
);
736 /* Takes operator name as e.g. "++" and returns mangled
737 operator name (e.g. "postincrement_expr"), or NULL if not found.
739 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
740 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
743 cplus_mangle_opname (opname
, options
)
750 len
= strlen (opname
);
751 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
753 if ((int) strlen (optable
[i
].out
) == len
754 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
755 && memcmp (optable
[i
].out
, opname
, len
) == 0)
756 return optable
[i
].in
;
761 /* char *cplus_demangle (const char *mangled, int options)
763 If MANGLED is a mangled function name produced by GNU C++, then
764 a pointer to a malloced string giving a C++ representation
765 of the name will be returned; otherwise NULL will be returned.
766 It is the caller's responsibility to free the string which
769 The OPTIONS arg may contain one or more of the following bits:
771 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
773 DMGL_PARAMS Function parameters are included.
777 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
778 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
779 cplus_demangle ("foo__1Ai", 0) => "A::foo"
781 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
782 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
783 cplus_demangle ("foo__1Afe", 0) => "A::foo"
785 Note that any leading underscores, or other such characters prepended by
786 the compilation system, are presumed to have already been stripped from
790 cplus_demangle (mangled
, options
)
795 struct work_stuff work
[1];
796 memset ((char *) work
, 0, sizeof (work
));
797 work
-> options
= options
;
798 if ((work
-> options
& DMGL_STYLE_MASK
) == 0)
799 work
-> options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
801 ret
= internal_cplus_demangle (work
, mangled
);
802 squangle_mop_up (work
);
807 /* This function performs most of what cplus_demangle use to do, but
808 to be able to demangle a name with a B, K or n code, we need to
809 have a longer term memory of what types have been seen. The original
810 now intializes and cleans up the squangle code info, while internal
811 calls go directly to this routine to avoid resetting that info. */
814 internal_cplus_demangle (work
, mangled
)
815 struct work_stuff
*work
;
821 char *demangled
= NULL
;
823 s1
= work
->constructor
;
824 s2
= work
->destructor
;
825 s3
= work
->static_type
;
826 s4
= work
->type_quals
;
827 work
->constructor
= work
->destructor
= 0;
828 work
->type_quals
= TYPE_UNQUALIFIED
;
829 work
->dllimported
= 0;
831 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
835 /* First check to see if gnu style demangling is active and if the
836 string to be demangled contains a CPLUS_MARKER. If so, attempt to
837 recognize one of the gnu special forms rather than looking for a
838 standard prefix. In particular, don't worry about whether there
839 is a "__" string in the mangled string. Consider "_$_5__foo" for
842 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
844 success
= gnu_special (work
, &mangled
, &decl
);
848 success
= demangle_prefix (work
, &mangled
, &decl
);
850 if (success
&& (*mangled
!= '\0'))
852 success
= demangle_signature (work
, &mangled
, &decl
);
854 if (work
->constructor
== 2)
856 string_prepend (&decl
, "global constructors keyed to ");
857 work
->constructor
= 0;
859 else if (work
->destructor
== 2)
861 string_prepend (&decl
, "global destructors keyed to ");
862 work
->destructor
= 0;
864 else if (work
->dllimported
== 1)
866 string_prepend (&decl
, "import stub for ");
867 work
->dllimported
= 0;
869 demangled
= mop_up (work
, &decl
, success
);
871 work
->constructor
= s1
;
872 work
->destructor
= s2
;
873 work
->static_type
= s3
;
874 work
->type_quals
= s4
;
879 /* Clear out and squangling related storage */
881 squangle_mop_up (work
)
882 struct work_stuff
*work
;
884 /* clean up the B and K type mangling types. */
885 forget_B_and_K_types (work
);
886 if (work
-> btypevec
!= NULL
)
888 free ((char *) work
-> btypevec
);
890 if (work
-> ktypevec
!= NULL
)
892 free ((char *) work
-> ktypevec
);
896 /* Clear out any mangled storage */
899 mop_up (work
, declp
, success
)
900 struct work_stuff
*work
;
904 char *demangled
= NULL
;
906 /* Discard the remembered types, if any. */
909 if (work
-> typevec
!= NULL
)
911 free ((char *) work
-> typevec
);
912 work
-> typevec
= NULL
;
913 work
-> typevec_size
= 0;
915 if (work
->tmpl_argvec
)
919 for (i
= 0; i
< work
->ntmpl_args
; i
++)
920 if (work
->tmpl_argvec
[i
])
921 free ((char*) work
->tmpl_argvec
[i
]);
923 free ((char*) work
->tmpl_argvec
);
924 work
->tmpl_argvec
= NULL
;
926 if (work
->previous_argument
)
928 string_delete (work
->previous_argument
);
929 free ((char*) work
->previous_argument
);
930 work
->previous_argument
= NULL
;
933 /* If demangling was successful, ensure that the demangled string is null
934 terminated and return it. Otherwise, free the demangling decl. */
938 string_delete (declp
);
942 string_appendn (declp
, "", 1);
943 demangled
= declp
-> b
;
952 demangle_signature -- demangle the signature part of a mangled name
957 demangle_signature (struct work_stuff *work, const char **mangled,
962 Consume and demangle the signature portion of the mangled name.
964 DECLP is the string where demangled output is being built. At
965 entry it contains the demangled root name from the mangled name
966 prefix. I.E. either a demangled operator name or the root function
967 name. In some special cases, it may contain nothing.
969 *MANGLED points to the current unconsumed location in the mangled
970 name. As tokens are consumed and demangling is performed, the
971 pointer is updated to continuously point at the next token to
974 Demangling GNU style mangled names is nasty because there is no
975 explicit token that marks the start of the outermost function
979 demangle_signature (work
, mangled
, declp
)
980 struct work_stuff
*work
;
981 const char **mangled
;
987 int expect_return_type
= 0;
988 const char *oldmangled
= NULL
;
992 while (success
&& (**mangled
!= '\0'))
997 oldmangled
= *mangled
;
998 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1000 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1001 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1007 oldmangled
= *mangled
;
1008 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1009 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1017 /* Static member function */
1018 if (oldmangled
== NULL
)
1020 oldmangled
= *mangled
;
1023 work
-> static_type
= 1;
1029 work
->type_quals
|= code_for_qualifier (**mangled
);
1031 /* a qualified member function */
1032 if (oldmangled
== NULL
)
1033 oldmangled
= *mangled
;
1038 /* Local class name follows after "Lnnn_" */
1041 while (**mangled
&& (**mangled
!= '_'))
1052 case '0': case '1': case '2': case '3': case '4':
1053 case '5': case '6': case '7': case '8': case '9':
1054 if (oldmangled
== NULL
)
1056 oldmangled
= *mangled
;
1058 work
->temp_start
= -1; /* uppermost call to demangle_class */
1059 success
= demangle_class (work
, mangled
, declp
);
1062 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1064 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1066 /* EDG and others will have the "F", so we let the loop cycle
1067 if we are looking at one. */
1068 if (**mangled
!= 'F')
1077 success
= do_type (work
, mangled
, &s
);
1080 string_append (&s
, SCOPE_STRING (work
));
1081 string_prepends (declp
, &s
);
1090 /* ARM/HP style demangling includes a specific 'F' character after
1091 the class name. For GNU style, it is just implied. So we can
1092 safely just consume any 'F' at this point and be compatible
1093 with either style. */
1099 /* For lucid/ARM/HP style we have to forget any types we might
1100 have remembered up to this point, since they were not argument
1101 types. GNU style considers all types seen as available for
1102 back references. See comment in demangle_args() */
1104 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1106 forget_types (work
);
1108 success
= demangle_args (work
, mangled
, declp
);
1109 /* After picking off the function args, we expect to either
1110 find the function return type (preceded by an '_') or the
1111 end of the string. */
1112 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1115 /* At this level, we do not care about the return type. */
1116 success
= do_type (work
, mangled
, &tname
);
1117 string_delete (&tname
);
1124 string_init(&trawname
);
1125 string_init(&tname
);
1126 if (oldmangled
== NULL
)
1128 oldmangled
= *mangled
;
1130 success
= demangle_template (work
, mangled
, &tname
,
1134 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1136 string_append (&tname
, SCOPE_STRING (work
));
1138 string_prepends(declp
, &tname
);
1139 if (work
-> destructor
& 1)
1141 string_prepend (&trawname
, "~");
1142 string_appends (declp
, &trawname
);
1143 work
->destructor
-= 1;
1145 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1147 string_appends (declp
, &trawname
);
1148 work
->constructor
-= 1;
1150 string_delete(&trawname
);
1151 string_delete(&tname
);
1157 if (GNU_DEMANGLING
&& expect_return_type
)
1159 /* Read the return type. */
1161 string_init (&return_type
);
1164 success
= do_type (work
, mangled
, &return_type
);
1165 APPEND_BLANK (&return_type
);
1167 string_prepends (declp
, &return_type
);
1168 string_delete (&return_type
);
1172 /* At the outermost level, we cannot have a return type specified,
1173 so if we run into another '_' at this point we are dealing with
1174 a mangled name that is either bogus, or has been mangled by
1175 some algorithm we don't know how to deal with. So just
1176 reject the entire demangling. */
1177 /* However, "_nnn" is an expected suffix for alternate entry point
1178 numbered nnn for a function, with HP aCC, so skip over that
1179 without reporting failure. pai/1997-09-04 */
1183 while (**mangled
&& isdigit ((unsigned char)**mangled
))
1193 /* A G++ template function. Read the template arguments. */
1194 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1196 if (!(work
->constructor
& 1))
1197 expect_return_type
= 1;
1206 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1208 /* Assume we have stumbled onto the first outermost function
1209 argument token, and start processing args. */
1211 success
= demangle_args (work
, mangled
, declp
);
1215 /* Non-GNU demanglers use a specific token to mark the start
1216 of the outermost function argument tokens. Typically 'F',
1217 for ARM/HP-demangling, for example. So if we find something
1218 we are not prepared for, it must be an error. */
1224 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1227 if (success
&& expect_func
)
1230 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1232 forget_types (work
);
1234 success
= demangle_args (work
, mangled
, declp
);
1235 /* Since template include the mangling of their return types,
1236 we must set expect_func to 0 so that we don't try do
1237 demangle more arguments the next time we get here. */
1242 if (success
&& !func_done
)
1244 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1246 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1247 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1248 first case, and need to ensure that the '(void)' gets added to
1249 the current declp. Note that with ARM/HP, the first case
1250 represents the name of a static data member 'foo::bar',
1251 which is in the current declp, so we leave it alone. */
1252 success
= demangle_args (work
, mangled
, declp
);
1255 if (success
&& PRINT_ARG_TYPES
)
1257 if (work
->static_type
)
1258 string_append (declp
, " static");
1259 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1261 APPEND_BLANK (declp
);
1262 string_append (declp
, qualifier_string (work
->type_quals
));
1272 demangle_method_args (work
, mangled
, declp
)
1273 struct work_stuff
*work
;
1274 const char **mangled
;
1279 if (work
-> static_type
)
1281 string_append (declp
, *mangled
+ 1);
1282 *mangled
+= strlen (*mangled
);
1287 success
= demangle_args (work
, mangled
, declp
);
1295 demangle_template_template_parm (work
, mangled
, tname
)
1296 struct work_stuff
*work
;
1297 const char **mangled
;
1306 string_append (tname
, "template <");
1307 /* get size of template parameter list */
1308 if (get_count (mangled
, &r
))
1310 for (i
= 0; i
< r
; i
++)
1314 string_append (tname
, ", ");
1317 /* Z for type parameters */
1318 if (**mangled
== 'Z')
1321 string_append (tname
, "class");
1323 /* z for template parameters */
1324 else if (**mangled
== 'z')
1328 demangle_template_template_parm (work
, mangled
, tname
);
1336 /* temp is initialized in do_type */
1337 success
= do_type (work
, mangled
, &temp
);
1340 string_appends (tname
, &temp
);
1342 string_delete(&temp
);
1352 if (tname
->p
[-1] == '>')
1353 string_append (tname
, " ");
1354 string_append (tname
, "> class");
1359 demangle_expression (work
, mangled
, s
, tk
)
1360 struct work_stuff
*work
;
1361 const char** mangled
;
1365 int need_operator
= 0;
1369 string_appendn (s
, "(", 1);
1371 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1380 len
= strlen (*mangled
);
1383 i
< sizeof (optable
) / sizeof (optable
[0]);
1386 size_t l
= strlen (optable
[i
].in
);
1389 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1391 string_appendn (s
, " ", 1);
1392 string_append (s
, optable
[i
].out
);
1393 string_appendn (s
, " ", 1);
1406 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1409 if (**mangled
!= 'W')
1413 string_appendn (s
, ")", 1);
1421 demangle_integral_value (work
, mangled
, s
)
1422 struct work_stuff
*work
;
1423 const char** mangled
;
1428 if (**mangled
== 'E')
1429 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1430 else if (**mangled
== 'Q' || **mangled
== 'K')
1431 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1438 /* Negative numbers are indicated with a leading `m'. */
1439 if (**mangled
== 'm')
1441 string_appendn (s
, "-", 1);
1445 /* Read the rest of the number. */
1446 value
= consume_count_with_underscores (mangled
);
1449 char buf
[INTBUF_SIZE
];
1450 sprintf (buf
, "%d", value
);
1451 string_append (s
, buf
);
1453 /* If the next character is an underscore, skip it. */
1454 if (**mangled
== '_')
1465 /* Demangle the real value in MANGLED. */
1468 demangle_real_value (work
, mangled
, s
)
1469 struct work_stuff
*work
;
1470 const char **mangled
;
1473 if (**mangled
== 'E')
1474 return demangle_expression (work
, mangled
, s
, tk_real
);
1476 if (**mangled
== 'm')
1478 string_appendn (s
, "-", 1);
1481 while (isdigit ((unsigned char)**mangled
))
1483 string_appendn (s
, *mangled
, 1);
1486 if (**mangled
== '.') /* fraction */
1488 string_appendn (s
, ".", 1);
1490 while (isdigit ((unsigned char)**mangled
))
1492 string_appendn (s
, *mangled
, 1);
1496 if (**mangled
== 'e') /* exponent */
1498 string_appendn (s
, "e", 1);
1500 while (isdigit ((unsigned char)**mangled
))
1502 string_appendn (s
, *mangled
, 1);
1511 demangle_template_value_parm (work
, mangled
, s
, tk
)
1512 struct work_stuff
*work
;
1513 const char **mangled
;
1519 if (**mangled
== 'Y')
1521 /* The next argument is a template parameter. */
1525 idx
= consume_count_with_underscores (mangled
);
1527 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1528 || consume_count_with_underscores (mangled
) == -1)
1530 if (work
->tmpl_argvec
)
1531 string_append (s
, work
->tmpl_argvec
[idx
]);
1533 string_append_template_idx (s
, idx
);
1535 else if (tk
== tk_integral
)
1536 success
= demangle_integral_value (work
, mangled
, s
);
1537 else if (tk
== tk_char
)
1541 if (**mangled
== 'm')
1543 string_appendn (s
, "-", 1);
1546 string_appendn (s
, "'", 1);
1547 val
= consume_count(mangled
);
1554 string_appendn (s
, &tmp
[0], 1);
1555 string_appendn (s
, "'", 1);
1558 else if (tk
== tk_bool
)
1560 int val
= consume_count (mangled
);
1562 string_appendn (s
, "false", 5);
1564 string_appendn (s
, "true", 4);
1568 else if (tk
== tk_real
)
1569 success
= demangle_real_value (work
, mangled
, s
);
1570 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1572 if (**mangled
== 'Q')
1573 success
= demangle_qualified (work
, mangled
, s
,
1578 int symbol_len
= consume_count (mangled
);
1579 if (symbol_len
== -1)
1581 if (symbol_len
== 0)
1582 string_appendn (s
, "0", 1);
1585 char *p
= xmalloc (symbol_len
+ 1), *q
;
1586 strncpy (p
, *mangled
, symbol_len
);
1587 p
[symbol_len
] = '\0';
1588 /* We use cplus_demangle here, rather than
1589 internal_cplus_demangle, because the name of the entity
1590 mangled here does not make use of any of the squangling
1591 or type-code information we have built up thus far; it is
1592 mangled independently. */
1593 q
= cplus_demangle (p
, work
->options
);
1594 if (tk
== tk_pointer
)
1595 string_appendn (s
, "&", 1);
1596 /* FIXME: Pointer-to-member constants should get a
1597 qualifying class name here. */
1600 string_append (s
, q
);
1604 string_append (s
, p
);
1607 *mangled
+= symbol_len
;
1614 /* Demangle the template name in MANGLED. The full name of the
1615 template (e.g., S<int>) is placed in TNAME. The name without the
1616 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1617 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1618 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1619 the tmeplate is remembered in the list of back-referenceable
1623 demangle_template (work
, mangled
, tname
, trawname
, is_type
, remember
)
1624 struct work_stuff
*work
;
1625 const char **mangled
;
1636 int is_java_array
= 0;
1644 bindex
= register_Btype (work
);
1646 /* get template name */
1647 if (**mangled
== 'z')
1653 idx
= consume_count_with_underscores (mangled
);
1655 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1656 || consume_count_with_underscores (mangled
) == -1)
1659 if (work
->tmpl_argvec
)
1661 string_append (tname
, work
->tmpl_argvec
[idx
]);
1663 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1667 string_append_template_idx (tname
, idx
);
1669 string_append_template_idx (trawname
, idx
);
1674 if ((r
= consume_count (mangled
)) <= 0
1675 || (int) strlen (*mangled
) < r
)
1679 is_java_array
= (work
-> options
& DMGL_JAVA
)
1680 && strncmp (*mangled
, "JArray1Z", 8) == 0;
1681 if (! is_java_array
)
1683 string_appendn (tname
, *mangled
, r
);
1686 string_appendn (trawname
, *mangled
, r
);
1691 string_append (tname
, "<");
1692 /* get size of template parameter list */
1693 if (!get_count (mangled
, &r
))
1699 /* Create an array for saving the template argument values. */
1700 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
1701 work
->ntmpl_args
= r
;
1702 for (i
= 0; i
< r
; i
++)
1703 work
->tmpl_argvec
[i
] = 0;
1705 for (i
= 0; i
< r
; i
++)
1709 string_append (tname
, ", ");
1711 /* Z for type parameters */
1712 if (**mangled
== 'Z')
1715 /* temp is initialized in do_type */
1716 success
= do_type (work
, mangled
, &temp
);
1719 string_appends (tname
, &temp
);
1723 /* Save the template argument. */
1724 int len
= temp
.p
- temp
.b
;
1725 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1726 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
1727 work
->tmpl_argvec
[i
][len
] = '\0';
1730 string_delete(&temp
);
1736 /* z for template parameters */
1737 else if (**mangled
== 'z')
1741 success
= demangle_template_template_parm (work
, mangled
, tname
);
1744 && (r2
= consume_count (mangled
)) > 0
1745 && (int) strlen (*mangled
) >= r2
)
1747 string_append (tname
, " ");
1748 string_appendn (tname
, *mangled
, r2
);
1751 /* Save the template argument. */
1753 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1754 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
1755 work
->tmpl_argvec
[i
][len
] = '\0';
1769 /* otherwise, value parameter */
1771 /* temp is initialized in do_type */
1772 success
= do_type (work
, mangled
, &temp
);
1773 string_delete(&temp
);
1785 success
= demangle_template_value_parm (work
, mangled
, s
,
1786 (type_kind_t
) success
);
1798 int len
= s
->p
- s
->b
;
1799 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
1800 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
1801 work
->tmpl_argvec
[i
][len
] = '\0';
1803 string_appends (tname
, s
);
1811 string_append (tname
, "[]");
1815 if (tname
->p
[-1] == '>')
1816 string_append (tname
, " ");
1817 string_append (tname
, ">");
1820 if (is_type
&& remember
)
1821 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
1824 if (work -> static_type)
1826 string_append (declp, *mangled + 1);
1827 *mangled += strlen (*mangled);
1832 success = demangle_args (work, mangled, declp);
1840 arm_pt (work
, mangled
, n
, anchor
, args
)
1841 struct work_stuff
*work
;
1842 const char *mangled
;
1844 const char **anchor
, **args
;
1846 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1847 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1848 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= mystrstr (mangled
, "__pt__")))
1851 *args
= *anchor
+ 6;
1852 len
= consume_count (args
);
1855 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1861 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
1863 if ((*anchor
= mystrstr (mangled
, "__tm__"))
1864 || (*anchor
= mystrstr (mangled
, "__ps__"))
1865 || (*anchor
= mystrstr (mangled
, "__pt__")))
1868 *args
= *anchor
+ 6;
1869 len
= consume_count (args
);
1872 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1878 else if ((*anchor
= mystrstr (mangled
, "__S")))
1881 *args
= *anchor
+ 3;
1882 len
= consume_count (args
);
1885 if (*args
+ len
== mangled
+ n
&& **args
== '_')
1897 demangle_arm_hp_template (work
, mangled
, n
, declp
)
1898 struct work_stuff
*work
;
1899 const char **mangled
;
1905 const char *e
= *mangled
+ n
;
1908 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1910 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
1912 char *start_spec_args
= NULL
;
1914 /* First check for and omit template specialization pseudo-arguments,
1915 such as in "Spec<#1,#1.*>" */
1916 start_spec_args
= strchr (*mangled
, '<');
1917 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
1918 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
1920 string_appendn (declp
, *mangled
, n
);
1921 (*mangled
) += n
+ 1;
1923 if (work
->temp_start
== -1) /* non-recursive call */
1924 work
->temp_start
= declp
->p
- declp
->b
;
1925 string_append (declp
, "<");
1928 string_clear (&arg
);
1932 /* 'T' signals a type parameter */
1934 if (!do_type (work
, mangled
, &arg
))
1935 goto hpacc_template_args_done
;
1940 /* 'U' or 'S' signals an integral value */
1941 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
1942 goto hpacc_template_args_done
;
1946 /* 'A' signals a named constant expression (literal) */
1947 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
1948 goto hpacc_template_args_done
;
1952 /* Today, 1997-09-03, we have only the above types
1953 of template parameters */
1954 /* FIXME: maybe this should fail and return null */
1955 goto hpacc_template_args_done
;
1957 string_appends (declp
, &arg
);
1958 /* Check if we're at the end of template args.
1959 0 if at end of static member of template class,
1960 _ if done with template args for a function */
1961 if ((**mangled
== '\000') || (**mangled
== '_'))
1964 string_append (declp
, ",");
1966 hpacc_template_args_done
:
1967 string_append (declp
, ">");
1968 string_delete (&arg
);
1969 if (**mangled
== '_')
1973 /* ARM template? (Also handles HP cfront extensions) */
1974 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
1979 string_appendn (declp
, *mangled
, p
- *mangled
);
1980 if (work
->temp_start
== -1) /* non-recursive call */
1981 work
->temp_start
= declp
->p
- declp
->b
;
1982 string_append (declp
, "<");
1983 /* should do error checking here */
1985 string_clear (&arg
);
1987 /* Check for type or literal here */
1990 /* HP cfront extensions to ARM for template args */
1991 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1992 /* FIXME: We handle only numeric literals for HP cfront */
1994 /* A typed constant value follows */
1996 if (!do_type (work
, &args
, &type_str
))
1997 goto cfront_template_args_done
;
1998 string_append (&arg
, "(");
1999 string_appends (&arg
, &type_str
);
2000 string_append (&arg
, ")");
2002 goto cfront_template_args_done
;
2004 /* Now snarf a literal value following 'L' */
2005 if (!snarf_numeric_literal (&args
, &arg
))
2006 goto cfront_template_args_done
;
2010 /* Snarf a literal following 'L' */
2012 if (!snarf_numeric_literal (&args
, &arg
))
2013 goto cfront_template_args_done
;
2016 /* Not handling other HP cfront stuff */
2017 if (!do_type (work
, &args
, &arg
))
2018 goto cfront_template_args_done
;
2020 string_appends (declp
, &arg
);
2021 string_append (declp
, ",");
2023 cfront_template_args_done
:
2024 string_delete (&arg
);
2026 --declp
->p
; /* remove extra comma */
2027 string_append (declp
, ">");
2029 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2030 && (*mangled
)[9] == 'N'
2031 && (*mangled
)[8] == (*mangled
)[10]
2032 && strchr (cplus_markers
, (*mangled
)[8]))
2034 /* A member of the anonymous namespace. */
2035 string_append (declp
, "{anonymous}");
2039 if (work
->temp_start
== -1) /* non-recursive call only */
2040 work
->temp_start
= 0; /* disable in recursive calls */
2041 string_appendn (declp
, *mangled
, n
);
2046 /* Extract a class name, possibly a template with arguments, from the
2047 mangled string; qualifiers, local class indicators, etc. have
2048 already been dealt with */
2051 demangle_class_name (work
, mangled
, declp
)
2052 struct work_stuff
*work
;
2053 const char **mangled
;
2059 n
= consume_count (mangled
);
2062 if ((int) strlen (*mangled
) >= n
)
2064 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2075 demangle_class -- demangle a mangled class sequence
2080 demangle_class (struct work_stuff *work, const char **mangled,
2085 DECLP points to the buffer into which demangling is being done.
2087 *MANGLED points to the current token to be demangled. On input,
2088 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2089 On exit, it points to the next token after the mangled class on
2090 success, or the first unconsumed token on failure.
2092 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2093 we are demangling a constructor or destructor. In this case
2094 we prepend "class::class" or "class::~class" to DECLP.
2096 Otherwise, we prepend "class::" to the current DECLP.
2098 Reset the constructor/destructor flags once they have been
2099 "consumed". This allows demangle_class to be called later during
2100 the same demangling, to do normal class demangling.
2102 Returns 1 if demangling is successful, 0 otherwise.
2107 demangle_class (work
, mangled
, declp
)
2108 struct work_stuff
*work
;
2109 const char **mangled
;
2115 char *save_class_name_end
= 0;
2117 string_init (&class_name
);
2118 btype
= register_Btype (work
);
2119 if (demangle_class_name (work
, mangled
, &class_name
))
2121 save_class_name_end
= class_name
.p
;
2122 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2124 /* adjust so we don't include template args */
2125 if (work
->temp_start
&& (work
->temp_start
!= -1))
2127 class_name
.p
= class_name
.b
+ work
->temp_start
;
2129 string_prepends (declp
, &class_name
);
2130 if (work
-> destructor
& 1)
2132 string_prepend (declp
, "~");
2133 work
-> destructor
-= 1;
2137 work
-> constructor
-= 1;
2140 class_name
.p
= save_class_name_end
;
2141 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2142 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2143 string_prepend (declp
, SCOPE_STRING (work
));
2144 string_prepends (declp
, &class_name
);
2147 string_delete (&class_name
);
2155 demangle_prefix -- consume the mangled name prefix and find signature
2160 demangle_prefix (struct work_stuff *work, const char **mangled,
2165 Consume and demangle the prefix of the mangled name.
2167 DECLP points to the string buffer into which demangled output is
2168 placed. On entry, the buffer is empty. On exit it contains
2169 the root function name, the demangled operator name, or in some
2170 special cases either nothing or the completely demangled result.
2172 MANGLED points to the current pointer into the mangled name. As each
2173 token of the mangled name is consumed, it is updated. Upon entry
2174 the current mangled name pointer points to the first character of
2175 the mangled name. Upon exit, it should point to the first character
2176 of the signature if demangling was successful, or to the first
2177 unconsumed character if demangling of the prefix was unsuccessful.
2179 Returns 1 on success, 0 otherwise.
2183 demangle_prefix (work
, mangled
, declp
)
2184 struct work_stuff
*work
;
2185 const char **mangled
;
2192 if (strlen(*mangled
) > 6
2193 && (strncmp(*mangled
, "_imp__", 6) == 0
2194 || strncmp(*mangled
, "__imp_", 6) == 0))
2196 /* it's a symbol imported from a PE dynamic library. Check for both
2197 new style prefix _imp__ and legacy __imp_ used by older versions
2200 work
->dllimported
= 1;
2202 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2204 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2205 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2207 if ((*mangled
)[9] == 'D')
2209 /* it's a GNU global destructor to be executed at program exit */
2211 work
->destructor
= 2;
2212 if (gnu_special (work
, mangled
, declp
))
2215 else if ((*mangled
)[9] == 'I')
2217 /* it's a GNU global constructor to be executed at program init */
2219 work
->constructor
= 2;
2220 if (gnu_special (work
, mangled
, declp
))
2225 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2227 /* it's a ARM global destructor to be executed at program exit */
2229 work
->destructor
= 2;
2231 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2233 /* it's a ARM global constructor to be executed at program initial */
2235 work
->constructor
= 2;
2238 /* This block of code is a reduction in strength time optimization
2240 scan = mystrstr (*mangled, "__"); */
2246 scan
= strchr (scan
, '_');
2247 } while (scan
!= NULL
&& *++scan
!= '_');
2249 if (scan
!= NULL
) --scan
;
2254 /* We found a sequence of two or more '_', ensure that we start at
2255 the last pair in the sequence. */
2256 i
= strspn (scan
, "_");
2267 else if (work
-> static_type
)
2269 if (!isdigit ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2274 else if ((scan
== *mangled
)
2275 && (isdigit ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2276 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2278 /* The ARM says nothing about the mangling of local variables.
2279 But cfront mangles local variables by prepending __<nesting_level>
2280 to them. As an extension to ARM demangling we handle this case. */
2281 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2282 && isdigit ((unsigned char)scan
[2]))
2284 *mangled
= scan
+ 2;
2285 consume_count (mangled
);
2286 string_append (declp
, *mangled
);
2287 *mangled
+= strlen (*mangled
);
2292 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2293 names like __Q2_3foo3bar for nested type names. So don't accept
2294 this style of constructor for cfront demangling. A GNU
2295 style member-template constructor starts with 'H'. */
2296 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2297 work
-> constructor
+= 1;
2298 *mangled
= scan
+ 2;
2301 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2303 /* Cfront-style parameterized type. Handled later as a signature. */
2307 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2309 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2310 || (scan
[2] == 'p' && scan
[3] == 's')
2311 || (scan
[2] == 'p' && scan
[3] == 't')))
2313 /* EDG-style parameterized type. Handled later as a signature. */
2317 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2319 else if ((scan
== *mangled
) && !isdigit ((unsigned char)scan
[2])
2320 && (scan
[2] != 't'))
2322 /* Mangled name starts with "__". Skip over any leading '_' characters,
2323 then find the next "__" that separates the prefix from the signature.
2325 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2326 || (arm_special (mangled
, declp
) == 0))
2328 while (*scan
== '_')
2332 if ((scan
= mystrstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2334 /* No separator (I.E. "__not_mangled"), or empty signature
2335 (I.E. "__not_mangled_either__") */
2342 /* Look for the LAST occurrence of __, allowing names to
2343 have the '__' sequence embedded in them. */
2344 if (!(ARM_DEMANGLING
|| HP_DEMANGLING
))
2346 while ((tmp
= mystrstr (scan
+ 2, "__")) != NULL
)
2349 if (*(scan
+ 2) == '\0')
2352 demangle_function_name (work
, mangled
, declp
, scan
);
2356 else if (*(scan
+ 2) != '\0')
2358 /* Mangled name does not start with "__" but does have one somewhere
2359 in there with non empty stuff after it. Looks like a global
2361 demangle_function_name (work
, mangled
, declp
, scan
);
2365 /* Doesn't look like a mangled name */
2369 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2371 string_append (declp
, *mangled
);
2372 *mangled
+= strlen (*mangled
);
2382 gnu_special -- special handling of gnu mangled strings
2387 gnu_special (struct work_stuff *work, const char **mangled,
2393 Process some special GNU style mangling forms that don't fit
2394 the normal pattern. For example:
2396 _$_3foo (destructor for class foo)
2397 _vt$foo (foo virtual table)
2398 _vt$foo$bar (foo::bar virtual table)
2399 __vt_foo (foo virtual table, new style with thunks)
2400 _3foo$varname (static data member)
2401 _Q22rs2tu$vw (static data member)
2402 __t6vector1Zii (constructor with template)
2403 __thunk_4__$_7ostream (virtual function thunk)
2407 gnu_special (work
, mangled
, declp
)
2408 struct work_stuff
*work
;
2409 const char **mangled
;
2416 if ((*mangled
)[0] == '_'
2417 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2418 && (*mangled
)[2] == '_')
2420 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2422 work
-> destructor
+= 1;
2424 else if ((*mangled
)[0] == '_'
2425 && (((*mangled
)[1] == '_'
2426 && (*mangled
)[2] == 'v'
2427 && (*mangled
)[3] == 't'
2428 && (*mangled
)[4] == '_')
2429 || ((*mangled
)[1] == 'v'
2430 && (*mangled
)[2] == 't'
2431 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2433 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2434 and create the decl. Note that we consume the entire mangled
2435 input string, which means that demangle_signature has no work
2437 if ((*mangled
)[2] == 'v')
2438 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2440 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2441 while (**mangled
!= '\0')
2447 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2450 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2454 if (isdigit((unsigned char)*mangled
[0]))
2456 n
= consume_count(mangled
);
2457 /* We may be seeing a too-large size, or else a
2458 ".<digits>" indicating a static local symbol. In
2459 any case, declare victory and move on; *don't* try
2460 to use n to allocate. */
2461 if (n
> (int) strlen (*mangled
))
2469 n
= strcspn (*mangled
, cplus_markers
);
2471 string_appendn (declp
, *mangled
, n
);
2475 p
= strpbrk (*mangled
, cplus_markers
);
2476 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2480 string_append (declp
, SCOPE_STRING (work
));
2491 string_append (declp
, " virtual table");
2493 else if ((*mangled
)[0] == '_'
2494 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2495 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2497 /* static data member, "_3foo$varname" for example */
2503 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2506 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2509 n
= consume_count (mangled
);
2510 if (n
< 0 || n
> (long) strlen (*mangled
))
2515 string_appendn (declp
, *mangled
, n
);
2518 if (success
&& (p
== *mangled
))
2520 /* Consumed everything up to the cplus_marker, append the
2523 string_append (declp
, SCOPE_STRING (work
));
2524 n
= strlen (*mangled
);
2525 string_appendn (declp
, *mangled
, n
);
2533 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2538 delta
= consume_count (mangled
);
2543 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2548 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2549 string_append (declp
, buf
);
2550 string_append (declp
, method
);
2552 n
= strlen (*mangled
);
2561 else if (strncmp (*mangled
, "__t", 3) == 0
2562 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2564 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2570 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2573 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2576 success
= demangle_fund_type (work
, mangled
, declp
);
2579 if (success
&& **mangled
!= '\0')
2582 string_append (declp
, p
);
2592 recursively_demangle(work
, mangled
, result
, namelength
)
2593 struct work_stuff
*work
;
2594 const char **mangled
;
2598 char * recurse
= (char *)NULL
;
2599 char * recurse_dem
= (char *)NULL
;
2601 recurse
= (char *) xmalloc (namelength
+ 1);
2602 memcpy (recurse
, *mangled
, namelength
);
2603 recurse
[namelength
] = '\000';
2605 recurse_dem
= cplus_demangle (recurse
, work
->options
);
2609 string_append (result
, recurse_dem
);
2614 string_appendn (result
, *mangled
, namelength
);
2617 *mangled
+= namelength
;
2624 arm_special -- special handling of ARM/lucid mangled strings
2629 arm_special (const char **mangled,
2635 Process some special ARM style mangling forms that don't fit
2636 the normal pattern. For example:
2638 __vtbl__3foo (foo virtual table)
2639 __vtbl__3foo__3bar (bar::foo virtual table)
2644 arm_special (mangled
, declp
)
2645 const char **mangled
;
2652 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
2654 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2655 and create the decl. Note that we consume the entire mangled
2656 input string, which means that demangle_signature has no work
2658 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
2659 while (*scan
!= '\0') /* first check it can be demangled */
2661 n
= consume_count (&scan
);
2664 return (0); /* no good */
2667 if (scan
[0] == '_' && scan
[1] == '_')
2672 (*mangled
) += ARM_VTABLE_STRLEN
;
2673 while (**mangled
!= '\0')
2675 n
= consume_count (mangled
);
2677 || n
> (long) strlen (*mangled
))
2679 string_prependn (declp
, *mangled
, n
);
2681 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
2683 string_prepend (declp
, "::");
2687 string_append (declp
, " virtual table");
2700 demangle_qualified -- demangle 'Q' qualified name strings
2705 demangle_qualified (struct work_stuff *, const char *mangled,
2706 string *result, int isfuncname, int append);
2710 Demangle a qualified name, such as "Q25Outer5Inner" which is
2711 the mangled form of "Outer::Inner". The demangled output is
2712 prepended or appended to the result string according to the
2713 state of the append flag.
2715 If isfuncname is nonzero, then the qualified name we are building
2716 is going to be used as a member function name, so if it is a
2717 constructor or destructor function, append an appropriate
2718 constructor or destructor name. I.E. for the above example,
2719 the result for use as a constructor is "Outer::Inner::Inner"
2720 and the result for use as a destructor is "Outer::Inner::~Inner".
2724 Numeric conversion is ASCII dependent (FIXME).
2729 demangle_qualified (work
, mangled
, result
, isfuncname
, append
)
2730 struct work_stuff
*work
;
2731 const char **mangled
;
2741 int bindex
= register_Btype (work
);
2743 /* We only make use of ISFUNCNAME if the entity is a constructor or
2745 isfuncname
= (isfuncname
2746 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
2748 string_init (&temp
);
2749 string_init (&last_name
);
2751 if ((*mangled
)[0] == 'K')
2753 /* Squangling qualified name reuse */
2756 idx
= consume_count_with_underscores (mangled
);
2757 if (idx
== -1 || idx
>= work
-> numk
)
2760 string_append (&temp
, work
-> ktypevec
[idx
]);
2763 switch ((*mangled
)[1])
2766 /* GNU mangled name with more than 9 classes. The count is preceded
2767 by an underscore (to distinguish it from the <= 9 case) and followed
2768 by an underscore. */
2770 qualifiers
= consume_count_with_underscores (mangled
);
2771 if (qualifiers
== -1)
2784 /* The count is in a single digit. */
2785 num
[0] = (*mangled
)[1];
2787 qualifiers
= atoi (num
);
2789 /* If there is an underscore after the digit, skip it. This is
2790 said to be for ARM-qualified names, but the ARM makes no
2791 mention of such an underscore. Perhaps cfront uses one. */
2792 if ((*mangled
)[2] == '_')
2807 /* Pick off the names and collect them in the temp buffer in the order
2808 in which they are found, separated by '::'. */
2810 while (qualifiers
-- > 0)
2813 string_clear (&last_name
);
2815 if (*mangled
[0] == '_')
2818 if (*mangled
[0] == 't')
2820 /* Here we always append to TEMP since we will want to use
2821 the template name without the template parameters as a
2822 constructor or destructor name. The appropriate
2823 (parameter-less) value is returned by demangle_template
2824 in LAST_NAME. We do not remember the template type here,
2825 in order to match the G++ mangling algorithm. */
2826 success
= demangle_template(work
, mangled
, &temp
,
2831 else if (*mangled
[0] == 'K')
2835 idx
= consume_count_with_underscores (mangled
);
2836 if (idx
== -1 || idx
>= work
->numk
)
2839 string_append (&temp
, work
->ktypevec
[idx
]);
2842 if (!success
) break;
2849 /* Now recursively demangle the qualifier
2850 * This is necessary to deal with templates in
2851 * mangling styles like EDG */
2852 namelength
= consume_count (mangled
);
2853 if (namelength
== -1)
2858 recursively_demangle(work
, mangled
, &temp
, namelength
);
2862 success
= do_type (work
, mangled
, &last_name
);
2865 string_appends (&temp
, &last_name
);
2870 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
2873 string_append (&temp
, SCOPE_STRING (work
));
2876 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
2878 /* If we are using the result as a function name, we need to append
2879 the appropriate '::' separated constructor or destructor name.
2880 We do this here because this is the most convenient place, where
2881 we already have a pointer to the name and the length of the name. */
2885 string_append (&temp
, SCOPE_STRING (work
));
2886 if (work
-> destructor
& 1)
2887 string_append (&temp
, "~");
2888 string_appends (&temp
, &last_name
);
2891 /* Now either prepend the temp buffer to the result, or append it,
2892 depending upon the state of the append flag. */
2895 string_appends (result
, &temp
);
2898 if (!STRING_EMPTY (result
))
2899 string_append (&temp
, SCOPE_STRING (work
));
2900 string_prepends (result
, &temp
);
2903 string_delete (&last_name
);
2904 string_delete (&temp
);
2912 get_count -- convert an ascii count to integer, consuming tokens
2917 get_count (const char **type, int *count)
2921 Assume that *type points at a count in a mangled name; set
2922 *count to its value, and set *type to the next character after
2923 the count. There are some weird rules in effect here.
2925 If *type does not point at a string of digits, return zero.
2927 If *type points at a string of digits followed by an
2928 underscore, set *count to their value as an integer, advance
2929 *type to point *after the underscore, and return 1.
2931 If *type points at a string of digits not followed by an
2932 underscore, consume only the first digit. Set *count to its
2933 value as an integer, leave *type pointing after that digit,
2936 The excuse for this odd behavior: in the ARM and HP demangling
2937 styles, a type can be followed by a repeat count of the form
2940 `x' is a single digit specifying how many additional copies
2941 of the type to append to the argument list, and
2943 `y' is one or more digits, specifying the zero-based index of
2944 the first repeated argument in the list. Yes, as you're
2945 unmangling the name you can figure this out yourself, but
2948 So, for example, in `bar__3fooFPiN51', the first argument is a
2949 pointer to an integer (`Pi'), and then the next five arguments
2950 are the same (`N5'), and the first repeat is the function's
2951 second argument (`1').
2955 get_count (type
, count
)
2962 if (!isdigit ((unsigned char)**type
))
2966 *count
= **type
- '0';
2968 if (isdigit ((unsigned char)**type
))
2978 while (isdigit ((unsigned char)*p
));
2989 /* RESULT will be initialised here; it will be freed on failure. The
2990 value returned is really a type_kind_t. */
2993 do_type (work
, mangled
, result
)
2994 struct work_stuff
*work
;
2995 const char **mangled
;
3002 const char *remembered_type
;
3005 type_kind_t tk
= tk_none
;
3007 string_init (&btype
);
3008 string_init (&decl
);
3009 string_init (result
);
3013 while (success
&& !done
)
3019 /* A pointer type */
3023 if (! (work
-> options
& DMGL_JAVA
))
3024 string_prepend (&decl
, "*");
3029 /* A reference type */
3032 string_prepend (&decl
, "&");
3041 if (!STRING_EMPTY (&decl
)
3042 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3044 string_prepend (&decl
, "(");
3045 string_append (&decl
, ")");
3047 string_append (&decl
, "[");
3048 if (**mangled
!= '_')
3049 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3051 if (**mangled
== '_')
3053 string_append (&decl
, "]");
3057 /* A back reference to a previously seen type */
3060 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3066 remembered_type
= work
-> typevec
[n
];
3067 mangled
= &remembered_type
;
3074 if (!STRING_EMPTY (&decl
)
3075 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3077 string_prepend (&decl
, "(");
3078 string_append (&decl
, ")");
3080 /* After picking off the function args, we expect to either find the
3081 function return type (preceded by an '_') or the end of the
3083 if (!demangle_nested_args (work
, mangled
, &decl
)
3084 || (**mangled
!= '_' && **mangled
!= '\0'))
3089 if (success
&& (**mangled
== '_'))
3096 type_quals
= TYPE_UNQUALIFIED
;
3098 member
= **mangled
== 'M';
3101 string_append (&decl
, ")");
3103 /* We don't need to prepend `::' for a qualified name;
3104 demangle_qualified will do that for us. */
3105 if (**mangled
!= 'Q')
3106 string_prepend (&decl
, SCOPE_STRING (work
));
3108 if (isdigit ((unsigned char)**mangled
))
3110 n
= consume_count (mangled
);
3112 || (int) strlen (*mangled
) < n
)
3117 string_prependn (&decl
, *mangled
, n
);
3120 else if (**mangled
== 'X' || **mangled
== 'Y')
3123 do_type (work
, mangled
, &temp
);
3124 string_prepends (&decl
, &temp
);
3126 else if (**mangled
== 't')
3129 string_init (&temp
);
3130 success
= demangle_template (work
, mangled
, &temp
,
3134 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3135 string_clear (&temp
);
3140 else if (**mangled
== 'Q')
3142 success
= demangle_qualified (work
, mangled
, &decl
,
3154 string_prepend (&decl
, "(");
3162 type_quals
|= code_for_qualifier (**mangled
);
3170 if (*(*mangled
)++ != 'F')
3176 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3177 || **mangled
!= '_')
3183 if (! PRINT_ANSI_QUALIFIERS
)
3187 if (type_quals
!= TYPE_UNQUALIFIED
)
3189 APPEND_BLANK (&decl
);
3190 string_append (&decl
, qualifier_string (type_quals
));
3201 if (PRINT_ANSI_QUALIFIERS
)
3203 if (!STRING_EMPTY (&decl
))
3204 string_prepend (&decl
, " ");
3206 string_prepend (&decl
, demangle_qualifier (**mangled
));
3221 if (success
) switch (**mangled
)
3223 /* A qualified name, such as "Outer::Inner". */
3227 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3231 /* A back reference to a previously seen squangled type */
3234 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3237 string_append (result
, work
->btypevec
[n
]);
3242 /* A template parm. We substitute the corresponding argument. */
3247 idx
= consume_count_with_underscores (mangled
);
3250 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3251 || consume_count_with_underscores (mangled
) == -1)
3257 if (work
->tmpl_argvec
)
3258 string_append (result
, work
->tmpl_argvec
[idx
]);
3260 string_append_template_idx (result
, idx
);
3267 success
= demangle_fund_type (work
, mangled
, result
);
3269 tk
= (type_kind_t
) success
;
3275 if (!STRING_EMPTY (&decl
))
3277 string_append (result
, " ");
3278 string_appends (result
, &decl
);
3282 string_delete (result
);
3283 string_delete (&decl
);
3286 /* Assume an integral type, if we're not sure. */
3287 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3292 /* Given a pointer to a type string that represents a fundamental type
3293 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3294 string in which the demangled output is being built in RESULT, and
3295 the WORK structure, decode the types and add them to the result.
3300 "Sl" => "signed long"
3301 "CUs" => "const unsigned short"
3303 The value returned is really a type_kind_t. */
3306 demangle_fund_type (work
, mangled
, result
)
3307 struct work_stuff
*work
;
3308 const char **mangled
;
3316 type_kind_t tk
= tk_integral
;
3318 string_init (&btype
);
3320 /* First pick off any type qualifiers. There can be more than one. */
3329 if (PRINT_ANSI_QUALIFIERS
)
3331 if (!STRING_EMPTY (result
))
3332 string_prepend (result
, " ");
3333 string_prepend (result
, demangle_qualifier (**mangled
));
3339 APPEND_BLANK (result
);
3340 string_append (result
, "unsigned");
3342 case 'S': /* signed char only */
3344 APPEND_BLANK (result
);
3345 string_append (result
, "signed");
3349 APPEND_BLANK (result
);
3350 string_append (result
, "__complex");
3358 /* Now pick off the fundamental type. There can be only one. */
3367 APPEND_BLANK (result
);
3368 string_append (result
, "void");
3372 APPEND_BLANK (result
);
3373 string_append (result
, "long long");
3377 APPEND_BLANK (result
);
3378 string_append (result
, "long");
3382 APPEND_BLANK (result
);
3383 string_append (result
, "int");
3387 APPEND_BLANK (result
);
3388 string_append (result
, "short");
3392 APPEND_BLANK (result
);
3393 string_append (result
, "bool");
3398 APPEND_BLANK (result
);
3399 string_append (result
, "char");
3404 APPEND_BLANK (result
);
3405 string_append (result
, "wchar_t");
3410 APPEND_BLANK (result
);
3411 string_append (result
, "long double");
3416 APPEND_BLANK (result
);
3417 string_append (result
, "double");
3422 APPEND_BLANK (result
);
3423 string_append (result
, "float");
3428 if (!isdigit ((unsigned char)**mangled
))
3435 if (**mangled
== '_')
3440 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3443 if (**mangled
!= '_')
3453 strncpy (buf
, *mangled
, 2);
3455 *mangled
+= min (strlen (*mangled
), 2);
3457 sscanf (buf
, "%x", &dec
);
3458 sprintf (buf
, "int%i_t", dec
);
3459 APPEND_BLANK (result
);
3460 string_append (result
, buf
);
3464 /* An explicit type, such as "6mytype" or "7integer" */
3476 int bindex
= register_Btype (work
);
3478 string_init (&btype
);
3479 if (demangle_class_name (work
, mangled
, &btype
)) {
3480 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3481 APPEND_BLANK (result
);
3482 string_appends (result
, &btype
);
3486 string_delete (&btype
);
3491 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3492 string_appends (result
, &btype
);
3500 return success
? ((int) tk
) : 0;
3504 /* Handle a template's value parameter for HP aCC (extension from ARM)
3505 **mangled points to 'S' or 'U' */
3508 do_hpacc_template_const_value (work
, mangled
, result
)
3509 struct work_stuff
*work ATTRIBUTE_UNUSED
;
3510 const char **mangled
;
3515 if (**mangled
!= 'U' && **mangled
!= 'S')
3518 unsigned_const
= (**mangled
== 'U');
3525 string_append (result
, "-");
3531 /* special case for -2^31 */
3532 string_append (result
, "-2147483648");
3539 /* We have to be looking at an integer now */
3540 if (!(isdigit ((unsigned char)**mangled
)))
3543 /* We only deal with integral values for template
3544 parameters -- so it's OK to look only for digits */
3545 while (isdigit ((unsigned char)**mangled
))
3547 char_str
[0] = **mangled
;
3548 string_append (result
, char_str
);
3553 string_append (result
, "U");
3555 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3556 with L or LL suffixes. pai/1997-09-03 */
3558 return 1; /* success */
3561 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3562 **mangled is pointing to the 'A' */
3565 do_hpacc_template_literal (work
, mangled
, result
)
3566 struct work_stuff
*work
;
3567 const char **mangled
;
3570 int literal_len
= 0;
3574 if (**mangled
!= 'A')
3579 literal_len
= consume_count (mangled
);
3581 if (literal_len
<= 0)
3584 /* Literal parameters are names of arrays, functions, etc. and the
3585 canonical representation uses the address operator */
3586 string_append (result
, "&");
3588 /* Now recursively demangle the literal name */
3589 recurse
= (char *) xmalloc (literal_len
+ 1);
3590 memcpy (recurse
, *mangled
, literal_len
);
3591 recurse
[literal_len
] = '\000';
3593 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3597 string_append (result
, recurse_dem
);
3602 string_appendn (result
, *mangled
, literal_len
);
3604 (*mangled
) += literal_len
;
3611 snarf_numeric_literal (args
, arg
)
3618 string_append (arg
, char_str
);
3621 else if (**args
== '+')
3624 if (!isdigit ((unsigned char)**args
))
3627 while (isdigit ((unsigned char)**args
))
3629 char_str
[0] = **args
;
3630 string_append (arg
, char_str
);
3637 /* Demangle the next argument, given by MANGLED into RESULT, which
3638 *should be an uninitialized* string. It will be initialized here,
3639 and free'd should anything go wrong. */
3642 do_arg (work
, mangled
, result
)
3643 struct work_stuff
*work
;
3644 const char **mangled
;
3647 /* Remember where we started so that we can record the type, for
3648 non-squangling type remembering. */
3649 const char *start
= *mangled
;
3651 string_init (result
);
3653 if (work
->nrepeats
> 0)
3657 if (work
->previous_argument
== 0)
3660 /* We want to reissue the previous type in this argument list. */
3661 string_appends (result
, work
->previous_argument
);
3665 if (**mangled
== 'n')
3667 /* A squangling-style repeat. */
3669 work
->nrepeats
= consume_count(mangled
);
3671 if (work
->nrepeats
<= 0)
3672 /* This was not a repeat count after all. */
3675 if (work
->nrepeats
> 9)
3677 if (**mangled
!= '_')
3678 /* The repeat count should be followed by an '_' in this
3685 /* Now, the repeat is all set up. */
3686 return do_arg (work
, mangled
, result
);
3689 /* Save the result in WORK->previous_argument so that we can find it
3690 if it's repeated. Note that saving START is not good enough: we
3691 do not want to add additional types to the back-referenceable
3692 type vector when processing a repeated type. */
3693 if (work
->previous_argument
)
3694 string_clear (work
->previous_argument
);
3697 work
->previous_argument
= (string
*) xmalloc (sizeof (string
));
3698 string_init (work
->previous_argument
);
3701 if (!do_type (work
, mangled
, work
->previous_argument
))
3704 string_appends (result
, work
->previous_argument
);
3706 remember_type (work
, start
, *mangled
- start
);
3711 remember_type (work
, start
, len
)
3712 struct work_stuff
*work
;
3718 if (work
->forgetting_types
)
3721 if (work
-> ntypes
>= work
-> typevec_size
)
3723 if (work
-> typevec_size
== 0)
3725 work
-> typevec_size
= 3;
3727 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
3731 work
-> typevec_size
*= 2;
3733 = (char **) xrealloc ((char *)work
-> typevec
,
3734 sizeof (char *) * work
-> typevec_size
);
3737 tem
= xmalloc (len
+ 1);
3738 memcpy (tem
, start
, len
);
3740 work
-> typevec
[work
-> ntypes
++] = tem
;
3744 /* Remember a K type class qualifier. */
3746 remember_Ktype (work
, start
, len
)
3747 struct work_stuff
*work
;
3753 if (work
-> numk
>= work
-> ksize
)
3755 if (work
-> ksize
== 0)
3759 = (char **) xmalloc (sizeof (char *) * work
-> ksize
);
3765 = (char **) xrealloc ((char *)work
-> ktypevec
,
3766 sizeof (char *) * work
-> ksize
);
3769 tem
= xmalloc (len
+ 1);
3770 memcpy (tem
, start
, len
);
3772 work
-> ktypevec
[work
-> numk
++] = tem
;
3775 /* Register a B code, and get an index for it. B codes are registered
3776 as they are seen, rather than as they are completed, so map<temp<char> >
3777 registers map<temp<char> > as B0, and temp<char> as B1 */
3780 register_Btype (work
)
3781 struct work_stuff
*work
;
3785 if (work
-> numb
>= work
-> bsize
)
3787 if (work
-> bsize
== 0)
3791 = (char **) xmalloc (sizeof (char *) * work
-> bsize
);
3797 = (char **) xrealloc ((char *)work
-> btypevec
,
3798 sizeof (char *) * work
-> bsize
);
3801 ret
= work
-> numb
++;
3802 work
-> btypevec
[ret
] = NULL
;
3806 /* Store a value into a previously registered B code type. */
3809 remember_Btype (work
, start
, len
, index
)
3810 struct work_stuff
*work
;
3816 tem
= xmalloc (len
+ 1);
3817 memcpy (tem
, start
, len
);
3819 work
-> btypevec
[index
] = tem
;
3822 /* Lose all the info related to B and K type codes. */
3824 forget_B_and_K_types (work
)
3825 struct work_stuff
*work
;
3829 while (work
-> numk
> 0)
3831 i
= --(work
-> numk
);
3832 if (work
-> ktypevec
[i
] != NULL
)
3834 free (work
-> ktypevec
[i
]);
3835 work
-> ktypevec
[i
] = NULL
;
3839 while (work
-> numb
> 0)
3841 i
= --(work
-> numb
);
3842 if (work
-> btypevec
[i
] != NULL
)
3844 free (work
-> btypevec
[i
]);
3845 work
-> btypevec
[i
] = NULL
;
3849 /* Forget the remembered types, but not the type vector itself. */
3853 struct work_stuff
*work
;
3857 while (work
-> ntypes
> 0)
3859 i
= --(work
-> ntypes
);
3860 if (work
-> typevec
[i
] != NULL
)
3862 free (work
-> typevec
[i
]);
3863 work
-> typevec
[i
] = NULL
;
3868 /* Process the argument list part of the signature, after any class spec
3869 has been consumed, as well as the first 'F' character (if any). For
3872 "__als__3fooRT0" => process "RT0"
3873 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3875 DECLP must be already initialised, usually non-empty. It won't be freed
3878 Note that g++ differs significantly from ARM and lucid style mangling
3879 with regards to references to previously seen types. For example, given
3880 the source fragment:
3884 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3887 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3888 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3890 g++ produces the names:
3895 while lcc (and presumably other ARM style compilers as well) produces:
3897 foo__FiR3fooT1T2T1T2
3898 __ct__3fooFiR3fooT1T2T1T2
3900 Note that g++ bases its type numbers starting at zero and counts all
3901 previously seen types, while lucid/ARM bases its type numbers starting
3902 at one and only considers types after it has seen the 'F' character
3903 indicating the start of the function args. For lucid/ARM style, we
3904 account for this difference by discarding any previously seen types when
3905 we see the 'F' character, and subtracting one from the type number
3911 demangle_args (work
, mangled
, declp
)
3912 struct work_stuff
*work
;
3913 const char **mangled
;
3923 if (PRINT_ARG_TYPES
)
3925 string_append (declp
, "(");
3926 if (**mangled
== '\0')
3928 string_append (declp
, "void");
3932 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
3933 || work
->nrepeats
> 0)
3935 if ((**mangled
== 'N') || (**mangled
== 'T'))
3937 temptype
= *(*mangled
)++;
3939 if (temptype
== 'N')
3941 if (!get_count (mangled
, &r
))
3950 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
3952 /* If we have 10 or more types we might have more than a 1 digit
3953 index so we'll have to consume the whole count here. This
3954 will lose if the next thing is a type name preceded by a
3955 count but it's impossible to demangle that case properly
3956 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3957 Pc, ...)" or "(..., type12, char *, ...)" */
3958 if ((t
= consume_count(mangled
)) <= 0)
3965 if (!get_count (mangled
, &t
))
3970 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
3974 /* Validate the type index. Protect against illegal indices from
3975 malformed type strings. */
3976 if ((t
< 0) || (t
>= work
-> ntypes
))
3980 while (work
->nrepeats
> 0 || --r
>= 0)
3982 tem
= work
-> typevec
[t
];
3983 if (need_comma
&& PRINT_ARG_TYPES
)
3985 string_append (declp
, ", ");
3987 if (!do_arg (work
, &tem
, &arg
))
3991 if (PRINT_ARG_TYPES
)
3993 string_appends (declp
, &arg
);
3995 string_delete (&arg
);
4001 if (need_comma
&& PRINT_ARG_TYPES
)
4002 string_append (declp
, ", ");
4003 if (!do_arg (work
, mangled
, &arg
))
4005 if (PRINT_ARG_TYPES
)
4006 string_appends (declp
, &arg
);
4007 string_delete (&arg
);
4012 if (**mangled
== 'e')
4015 if (PRINT_ARG_TYPES
)
4019 string_append (declp
, ",");
4021 string_append (declp
, "...");
4025 if (PRINT_ARG_TYPES
)
4027 string_append (declp
, ")");
4032 /* Like demangle_args, but for demangling the argument lists of function
4033 and method pointers or references, not top-level declarations. */
4036 demangle_nested_args (work
, mangled
, declp
)
4037 struct work_stuff
*work
;
4038 const char **mangled
;
4041 string
* saved_previous_argument
;
4045 /* The G++ name-mangling algorithm does not remember types on nested
4046 argument lists, unless -fsquangling is used, and in that case the
4047 type vector updated by remember_type is not used. So, we turn
4048 off remembering of types here. */
4049 ++work
->forgetting_types
;
4051 /* For the repeat codes used with -fsquangling, we must keep track of
4052 the last argument. */
4053 saved_previous_argument
= work
->previous_argument
;
4054 saved_nrepeats
= work
->nrepeats
;
4055 work
->previous_argument
= 0;
4058 /* Actually demangle the arguments. */
4059 result
= demangle_args (work
, mangled
, declp
);
4061 /* Restore the previous_argument field. */
4062 if (work
->previous_argument
)
4063 string_delete (work
->previous_argument
);
4064 work
->previous_argument
= saved_previous_argument
;
4065 --work
->forgetting_types
;
4066 work
->nrepeats
= saved_nrepeats
;
4072 demangle_function_name (work
, mangled
, declp
, scan
)
4073 struct work_stuff
*work
;
4074 const char **mangled
;
4082 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4083 string_need (declp
, 1);
4084 *(declp
-> p
) = '\0';
4086 /* Consume the function name, including the "__" separating the name
4087 from the signature. We are guaranteed that SCAN points to the
4090 (*mangled
) = scan
+ 2;
4091 /* We may be looking at an instantiation of a template function:
4092 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4093 following _F marks the start of the function arguments. Handle
4094 the template arguments first. */
4096 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4098 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4099 /* This leaves MANGLED pointing to the 'F' marking func args */
4102 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4105 /* See if we have an ARM style constructor or destructor operator.
4106 If so, then just record it, clear the decl, and return.
4107 We can't build the actual constructor/destructor decl until later,
4108 when we recover the class name from the signature. */
4110 if (strcmp (declp
-> b
, "__ct") == 0)
4112 work
-> constructor
+= 1;
4113 string_clear (declp
);
4116 else if (strcmp (declp
-> b
, "__dt") == 0)
4118 work
-> destructor
+= 1;
4119 string_clear (declp
);
4124 if (declp
->p
- declp
->b
>= 3
4125 && declp
->b
[0] == 'o'
4126 && declp
->b
[1] == 'p'
4127 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4129 /* see if it's an assignment expression */
4130 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4131 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4133 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4135 int len
= declp
->p
- declp
->b
- 10;
4136 if ((int) strlen (optable
[i
].in
) == len
4137 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4139 string_clear (declp
);
4140 string_append (declp
, "operator");
4141 string_append (declp
, optable
[i
].out
);
4142 string_append (declp
, "=");
4149 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4151 int len
= declp
->p
- declp
->b
- 3;
4152 if ((int) strlen (optable
[i
].in
) == len
4153 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4155 string_clear (declp
);
4156 string_append (declp
, "operator");
4157 string_append (declp
, optable
[i
].out
);
4163 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4164 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4166 /* type conversion operator */
4168 if (do_type (work
, &tem
, &type
))
4170 string_clear (declp
);
4171 string_append (declp
, "operator ");
4172 string_appends (declp
, &type
);
4173 string_delete (&type
);
4176 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4177 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4180 /* type conversion operator. */
4182 if (do_type (work
, &tem
, &type
))
4184 string_clear (declp
);
4185 string_append (declp
, "operator ");
4186 string_appends (declp
, &type
);
4187 string_delete (&type
);
4190 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4191 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
4192 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
4194 if (declp
->b
[4] == '\0')
4197 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4199 if (strlen (optable
[i
].in
) == 2
4200 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4202 string_clear (declp
);
4203 string_append (declp
, "operator");
4204 string_append (declp
, optable
[i
].out
);
4211 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4214 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
4216 if (strlen (optable
[i
].in
) == 3
4217 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4219 string_clear (declp
);
4220 string_append (declp
, "operator");
4221 string_append (declp
, optable
[i
].out
);
4230 /* a mini string-handling package */
4245 s
->p
= s
->b
= xmalloc (n
);
4248 else if (s
->e
- s
->p
< n
)
4253 s
->b
= xrealloc (s
->b
, n
);
4266 s
->b
= s
->e
= s
->p
= NULL
;
4274 s
->b
= s
->p
= s
->e
= NULL
;
4290 return (s
->b
== s
->p
);
4296 string_append (p
, s
)
4301 if (s
== NULL
|| *s
== '\0')
4305 memcpy (p
->p
, s
, n
);
4310 string_appends (p
, s
)
4319 memcpy (p
->p
, s
->b
, n
);
4325 string_appendn (p
, s
, n
)
4333 memcpy (p
->p
, s
, n
);
4339 string_prepend (p
, s
)
4343 if (s
!= NULL
&& *s
!= '\0')
4345 string_prependn (p
, s
, strlen (s
));
4350 string_prepends (p
, s
)
4355 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4360 string_prependn (p
, s
, n
)
4370 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4374 memcpy (p
->b
, s
, n
);
4380 string_append_template_idx (s
, idx
)
4384 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4385 sprintf(buf
, "T%d", idx
);
4386 string_append (s
, buf
);
4389 /* To generate a standalone demangler program for testing purposes,
4390 just compile and link this file with -DMAIN and libiberty.a. When
4391 run, it demangles each command line arg, or each stdin string, and
4392 prints the result on stdout. */
4398 static const char *program_name
;
4399 static const char *program_version
= VERSION
;
4400 static int flags
= DMGL_PARAMS
| DMGL_ANSI
;
4402 static void demangle_it
PARAMS ((char *));
4403 static void usage
PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN
;
4404 static void fatal
PARAMS ((const char *)) ATTRIBUTE_NORETURN
;
4407 demangle_it (mangled_name
)
4412 result
= cplus_demangle (mangled_name
, flags
);
4415 printf ("%s\n", mangled_name
);
4419 printf ("%s\n", result
);
4425 usage (stream
, status
)
4430 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4431 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4432 [--help] [--version] [arg...]\n",
4437 #define MBUF_SIZE 32767
4438 char mbuffer
[MBUF_SIZE
];
4440 /* Defined in the automatically-generated underscore.c. */
4441 extern int prepends_underscore
;
4443 int strip_underscore
= 0;
4445 static struct option long_options
[] = {
4446 {"strip-underscores", no_argument
, 0, '_'},
4447 {"format", required_argument
, 0, 's'},
4448 {"help", no_argument
, 0, 'h'},
4449 {"java", no_argument
, 0, 'j'},
4450 {"no-strip-underscores", no_argument
, 0, 'n'},
4451 {"version", no_argument
, 0, 'v'},
4452 {0, no_argument
, 0, 0}
4455 /* More 'friendly' abort that prints the line and file.
4456 config.h can #define abort fancy_abort if you like that sort of thing. */
4461 fatal ("Internal gcc abort.");
4466 standard_symbol_characters
PARAMS ((void));
4469 hp_symbol_characters
PARAMS ((void));
4471 /* Return the string of non-alnum characters that may occur
4472 as a valid symbol component, in the standard assembler symbol
4476 standard_symbol_characters ()
4482 /* Return the string of non-alnum characters that may occur
4483 as a valid symbol name component in an HP object file.
4485 Note that, since HP's compiler generates object code straight from
4486 C++ source, without going through an assembler, its mangled
4487 identifiers can use all sorts of characters that no assembler would
4488 tolerate, so the alphabet this function creates is a little odd.
4489 Here are some sample mangled identifiers offered by HP:
4491 typeid*__XT24AddressIndExpClassMember_
4492 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4493 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4495 This still seems really weird to me, since nowhere else in this
4496 file is there anything to recognize curly brackets, parens, etc.
4497 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4498 this is right, but I still strongly suspect that there's a
4499 misunderstanding here.
4501 If we decide it's better for c++filt to use HP's assembler syntax
4502 to scrape identifiers out of its input, here's the definition of
4503 the symbol name syntax from the HP assembler manual:
4505 Symbols are composed of uppercase and lowercase letters, decimal
4506 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4507 underscore (_). A symbol can begin with a letter, digit underscore or
4508 dollar sign. If a symbol begins with a digit, it must contain a
4509 non-digit character.
4513 hp_symbol_characters ()
4515 return "_$.<>#,*&[]:(){}";
4519 extern int main
PARAMS ((int, char **));
4528 const char *valid_symbols
;
4530 program_name
= argv
[0];
4532 strip_underscore
= prepends_underscore
;
4534 while ((c
= getopt_long (argc
, argv
, "_ns:j", long_options
, (int *) 0)) != EOF
)
4544 strip_underscore
= 0;
4547 printf ("GNU %s (C++ demangler), version %s\n", program_name
, program_version
);
4550 strip_underscore
= 1;
4556 if (strcmp (optarg
, "gnu") == 0)
4558 current_demangling_style
= gnu_demangling
;
4560 else if (strcmp (optarg
, "lucid") == 0)
4562 current_demangling_style
= lucid_demangling
;
4564 else if (strcmp (optarg
, "arm") == 0)
4566 current_demangling_style
= arm_demangling
;
4568 else if (strcmp (optarg
, "hp") == 0)
4570 current_demangling_style
= hp_demangling
;
4572 else if (strcmp (optarg
, "edg") == 0)
4574 current_demangling_style
= edg_demangling
;
4578 fprintf (stderr
, "%s: unknown demangling style `%s'\n",
4579 program_name
, optarg
);
4588 for ( ; optind
< argc
; optind
++)
4590 demangle_it (argv
[optind
]);
4595 switch (current_demangling_style
)
4597 case gnu_demangling
:
4598 case lucid_demangling
:
4599 case arm_demangling
:
4600 case edg_demangling
:
4601 valid_symbols
= standard_symbol_characters ();
4604 valid_symbols
= hp_symbol_characters ();
4607 /* Folks should explicitly indicate the appropriate alphabet for
4608 each demangling. Providing a default would allow the
4609 question to go unconsidered. */
4617 /* Try to read a label. */
4618 while (c
!= EOF
&& (isalnum (c
) || strchr (valid_symbols
, c
)))
4620 if (i
>= MBUF_SIZE
-1)
4629 if (mbuffer
[0] == '.')
4631 if (strip_underscore
&& mbuffer
[skip_first
] == '_')
4639 result
= cplus_demangle (mbuffer
+ skip_first
, flags
);
4642 if (mbuffer
[0] == '.')
4644 fputs (result
, stdout
);
4648 fputs (mbuffer
, stdout
);
4665 fprintf (stderr
, "%s: %s\n", program_name
, str
);
4673 register PTR value
= (PTR
) malloc (size
);
4675 fatal ("virtual memory exhausted");
4680 xrealloc (ptr
, size
)
4684 register PTR value
= (PTR
) realloc (ptr
, size
);
4686 fatal ("virtual memory exhausted");