1 // C++ IA64 / g++ v3 demangler -*- C++ -*-
3 // Copyright (C) 2003 Free Software Foundation, Inc.
4 // Written by Carlo Wood <carlo@alinoe.com>
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
32 #define __DEMANGLER_H 1
39 #ifndef _GLIBCPP_DEMANGLER_DEBUG
40 #define _GLIBCPP_DEMANGLER_CWDEBUG 0
41 #define _GLIBCPP_DEMANGLER_DEBUG(x)
42 #define _GLIBCPP_DEMANGLER_DOUT(cntrl, data)
43 #define _GLIBCPP_DEMANGLER_DOUT_ENTERING(x)
44 #define _GLIBCPP_DEMANGLER_DOUT_ENTERING2(x)
45 #define _GLIBCPP_DEMANGLER_RETURN \
47 #define _GLIBCPP_DEMANGLER_RETURN2 \
49 #define _GLIBCPP_DEMANGLER_FAILURE \
50 do { M_result = false; return false; } while(0)
52 #define _GLIBCPP_DEMANGLER_CWDEBUG 1
55 // The following defines change the behaviour of the demangler. The
56 // default behaviour is that none of these macros is defined.
58 // _GLIBCPP_DEMANGLER_STYLE_VOID
59 // Default behaviour: int f()
60 // Uses (void) instead of (): int f(void)
62 // _GLIBCPP_DEMANGLER_STYLE_LITERAL
63 // Default behaviour: (long)13,
64 // (unsigned long long)19
65 // Use extensions 'u', 'l' and 'll' for integral
66 // literals (as in template arguments): 13l, 19ull
68 // _GLIBCPP_DEMANGLER_STYLE_LITERAL_INT
69 // Default behaviour: 4
70 // Use also an explicit cast for int in literals: (int)4
80 template_template_param,
82 nested_name_template_prefix,
83 unscoped_template_name,
86 struct substitution_st
89 substitution_nt M_type;
90 int M_number_of_prefixes;
92 substitution_st(int start_pos,
94 int number_of_prefixes)
95 : M_start_pos(start_pos), M_type(type),
96 M_number_of_prefixes(number_of_prefixes)
100 enum simple_qualifier_nt
102 complex_or_imaginary = 'G',
112 enum param_qualifier_nt
114 vendor_extension = 'U',
116 pointer_to_member = 'M'
119 template<typename Allocator>
122 template<typename Allocator>
123 class qualifier_list;
125 template<typename Allocator>
128 template<typename Allocator>
131 typedef std::basic_string<char, std::char_traits<char>, Allocator>
138 mutable unsigned char M_cnt;
139 string_type M_optional_type;
141 bool M_part_of_substitution;
144 qualifier(int start_pos,
145 simple_qualifier_nt simple_qualifier,
146 int inside_substitution)
147 : M_qualifier1(simple_qualifier),
148 M_start_pos(start_pos),
149 M_part_of_substitution(inside_substitution)
152 qualifier(int start_pos,
153 cv_qualifier_nt cv_qualifier,
156 int inside_substitution)
157 : M_qualifier1(start[0]),
158 M_qualifier2((count > 1) ? start[1] : '\0'),
159 M_qualifier3((count > 2) ? start[2] : '\0'),
160 M_start_pos(start_pos),
161 M_part_of_substitution(inside_substitution)
164 qualifier(int start_pos,
165 param_qualifier_nt param_qualifier,
166 string_type optional_type,
167 int inside_substitution)
168 : M_qualifier1(param_qualifier),
169 M_optional_type(optional_type),
170 M_start_pos(start_pos),
171 M_part_of_substitution(inside_substitution)
175 get_start_pos(void) const
176 { return M_start_pos; }
179 first_qualifier(void) const
180 { M_cnt = 1; return M_qualifier1; }
183 next_qualifier(void) const
185 return (++M_cnt == 2) ? M_qualifier2
186 : ((M_cnt == 3) ? M_qualifier3 : 0);
190 get_optional_type(void) const
191 { return M_optional_type; }
194 part_of_substitution(void) const
195 { return M_part_of_substitution; }
199 template<typename Allocator>
202 typedef std::basic_string<char, std::char_traits<char>, Allocator>
206 bool M_printing_suppressed;
207 std::vector<qualifier<Allocator>, Allocator> M_qualifier_starts;
208 session<Allocator>& M_demangler;
211 qualifier_list(session<Allocator>& demangler_obj)
212 : M_printing_suppressed(false), M_demangler(demangler_obj)
216 add_qualifier_start(simple_qualifier_nt simple_qualifier,
218 int inside_substitution)
219 { M_qualifier_starts.
220 push_back(qualifier<Allocator>(start_pos,
221 simple_qualifier, inside_substitution)); }
224 add_qualifier_start(cv_qualifier_nt cv_qualifier,
227 int inside_substitution)
228 { M_qualifier_starts.
229 push_back(qualifier<Allocator>(start_pos,
230 cv_qualifier, &M_demangler.M_str[start_pos],
231 count, inside_substitution)); }
234 add_qualifier_start(param_qualifier_nt param_qualifier,
236 string_type optional_type,
237 int inside_substitution)
238 { M_qualifier_starts.
239 push_back(qualifier<Allocator>(start_pos,
240 param_qualifier, optional_type, inside_substitution)); }
243 decode_qualifiers(string_type& prefix,
244 string_type& postfix,
245 bool member_function_pointer_qualifiers);
248 suppressed(void) const
249 { return M_printing_suppressed; }
252 printing_suppressed(void)
253 { M_printing_suppressed = true; }
257 { return M_qualifier_starts.size(); }
261 template<typename Allocator>
264 friend class qualifier_list<Allocator>;
265 typedef std::basic_string<char, std::char_traits<char>, Allocator>
273 int M_inside_template_args;
275 int M_inside_substitution;
276 bool M_saw_destructor;
277 bool M_name_is_cdtor;
278 bool M_name_is_template;
279 bool M_name_is_conversion_operator;
280 bool M_template_args_need_space;
281 string_type M_function_name;
282 std::vector<int, Allocator> M_template_arg_pos;
283 int M_template_arg_pos_offset;
284 std::vector<substitution_st, Allocator> M_substitutions_pos;
285 #if _GLIBCPP_DEMANGLER_CWDEBUG
286 bool M_inside_add_substitution;
290 explicit session(char const* in, int len)
291 : M_str(in), M_pos(0), M_maxpos(len - 1), M_result(true),
292 M_inside_template_args(0), M_inside_type(0),
293 M_inside_substitution(0), M_saw_destructor(false),
294 M_name_is_cdtor(false), M_name_is_template(false),
295 M_name_is_conversion_operator(false),
296 M_template_args_need_space(false), M_template_arg_pos_offset(0)
297 #if _GLIBCPP_DEMANGLER_CWDEBUG
298 , M_inside_add_substitution(false)
303 decode_encoding(string_type& output, char const* input, int len);
306 decode_type_with_postfix(string_type& prefix,
307 string_type& postfix,
308 qualifier_list<Allocator>* qualifiers = NULL);
311 decode_type(string_type& output,
312 qualifier_list<Allocator>* qualifiers = NULL)
315 bool res = decode_type_with_postfix(output, postfix, qualifiers);
321 remaining_input_characters(void) const
322 { return current() != 0; }
327 { return (M_pos > M_maxpos) ? 0 : M_str[M_pos]; }
331 { return (M_pos >= M_maxpos) ? 0 : M_str[++M_pos]; }
335 { return (M_pos > M_maxpos) ? 0 : M_str[M_pos++]; }
338 store(int& saved_pos)
339 { saved_pos = M_pos; }
342 restore(int saved_pos)
343 { M_pos = saved_pos; M_result = true; }
346 add_substitution(int start_pos,
347 substitution_nt sub_type,
348 int number_of_prefixes);
350 bool decode_bare_function_type(string_type& output);
351 bool decode_builtin_type(string_type& output);
352 bool decode_call_offset(string_type& output);
353 bool decode_class_enum_type(string_type& output);
354 bool decode_expression(string_type& output);
355 bool decode_literal(string_type& output);
356 bool decode_local_name(string_type& output);
357 bool decode_name(string_type& output,
358 string_type& nested_name_qualifiers);
359 bool decode_nested_name(string_type& output,
360 string_type& qualifiers);
361 bool decode_number(string_type& output);
362 bool decode_operator_name(string_type& output);
363 bool decode_source_name(string_type& output);
364 bool decode_substitution(string_type& output,
365 qualifier_list<Allocator>* qualifiers = NULL);
366 bool decode_template_args(string_type& output);
367 bool decode_template_param(string_type& output,
368 qualifier_list<Allocator>* qualifiers = NULL);
369 bool decode_unqualified_name(string_type& output);
370 bool decode_unscoped_name(string_type& output);
371 bool decode_decimal_integer(string_type& output);
372 bool decode_special_name(string_type& output);
375 template<typename Allocator>
376 #if !_GLIBCPP_DEMANGLER_CWDEBUG
380 session<Allocator>::add_substitution(int start_pos,
381 substitution_nt sub_type,
382 int number_of_prefixes = 0)
384 if (!M_inside_substitution)
386 #if _GLIBCPP_DEMANGLER_CWDEBUG
387 if (M_inside_add_substitution)
391 push_back(substitution_st(start_pos,
392 sub_type, number_of_prefixes));
393 #if _GLIBCPP_DEMANGLER_CWDEBUG
394 if (!DEBUGCHANNELS::dc::demangler.is_on())
396 string_type substitution_name("S");
397 int n = M_substitutions_pos.size() - 1;
399 substitution_name += (n <= 10) ? (char)(n + '0' - 1)
400 : (char)(n + 'A' - 11);
401 substitution_name += '_';
403 int saved_pos = M_pos;
405 M_inside_add_substitution = true;
406 _GLIBCPP_DEMANGLER_DEBUG( dc::demangler.off() );
412 case template_template_param:
413 decode_template_param(subst);
415 case nested_name_prefix:
416 case nested_name_template_prefix:
417 for (int cnt = number_of_prefixes; cnt > 0; --cnt)
419 if (current() == 'I')
422 decode_template_args(subst);
426 if (cnt < number_of_prefixes)
428 if (current() == 'S')
429 decode_substitution(subst);
431 decode_unqualified_name(subst);
435 case unscoped_template_name:
436 decode_unscoped_name(subst);
440 _GLIBCPP_DEMANGLER_DEBUG( dc::demangler.on() );
441 _GLIBCPP_DEMANGLER_DOUT(dc::demangler,
442 "Adding substitution " << substitution_name
444 << " (from " << location_ct((char*)__builtin_return_address(0)
445 + builtin_return_address_offset)
446 << " <- " << location_ct((char*)__builtin_return_address(1)
447 + builtin_return_address_offset)
448 << " <- " << location_ct((char*)__builtin_return_address(2)
449 + builtin_return_address_offset)
451 M_inside_add_substitution = false;
457 // <decimal-integer> ::= 0
458 // ::= 1|2|3|4|5|6|7|8|9 [<digit>+]
459 // <digit> ::= 0|1|2|3|4|5|6|7|8|9
461 template<typename Allocator>
463 session<Allocator>::decode_decimal_integer(string_type& output)
471 else if (!std::isdigit(c))
479 while (std::isdigit((c = next())));
484 // <number> ::= [n] <decimal-integer>
486 template<typename Allocator>
488 session<Allocator>::decode_number(string_type& output)
490 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_number");
491 if (current() != 'n')
492 decode_decimal_integer(output);
497 decode_decimal_integer(output);
499 _GLIBCPP_DEMANGLER_RETURN;
502 // <builtin-type> ::= v # void
506 // ::= a # signed char
507 // ::= h # unsigned char
509 // ::= t # unsigned short
511 // ::= j # unsigned int
513 // ::= m # unsigned long
514 // ::= x # long long, __int64
515 // ::= y # unsigned long long, __int64
517 // ::= o # unsigned __int128
520 // ::= e # long double, __float80
521 // ::= g # __float128
523 // ::= u <source-name> # vendor extended type
525 char const* const builtin_type_c[26] =
534 "unsigned char", // h
539 "unsigned long", // m
541 "unsigned __int128", // o
546 "unsigned short", // t
551 "unsigned long long", // y
556 template<typename Allocator>
558 session<Allocator>::decode_builtin_type(string_type& output)
560 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_builtin_type");
562 if (!islower(current()) || !(bt = builtin_type_c[current() - 'a']))
563 _GLIBCPP_DEMANGLER_FAILURE;
566 _GLIBCPP_DEMANGLER_RETURN;
569 // <class-enum-type> ::= <name>
571 template<typename Allocator>
573 session<Allocator>::decode_class_enum_type(string_type& output)
575 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_class_enum_type");
576 string_type nested_name_qualifiers;
577 if (!decode_name(output, nested_name_qualifiers))
578 _GLIBCPP_DEMANGLER_FAILURE;
579 output += nested_name_qualifiers;
580 _GLIBCPP_DEMANGLER_RETURN;
583 // <substitution> ::=
587 // Sa # ::std::allocator
588 // Sb # ::std::basic_string
589 // Ss # ::std::basic_string<char, std::char_traits<char>,
590 // std::allocator<char> >
591 // Si # ::std::basic_istream<char, std::char_traits<char> >
592 // So # ::std::basic_ostream<char, std::char_traits<char> >
593 // Sd # ::std::basic_iostream<char, std::char_traits<char> >
596 // 0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
597 // [<seq-id>] # Base 36 number
599 template<typename Allocator>
601 session<Allocator>::decode_substitution(string_type& output,
602 qualifier_list<Allocator>* qualifiers)
604 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_substitution");
605 unsigned int value = 0;
613 output += "std::allocator";
614 if (!M_inside_template_args)
616 M_function_name = "allocator";
617 M_name_is_template = true;
618 M_name_is_cdtor = false;
619 M_name_is_conversion_operator = false;
623 qualifiers->printing_suppressed();
624 _GLIBCPP_DEMANGLER_RETURN;
628 output += "std::basic_string";
629 if (!M_inside_template_args)
631 M_function_name = "basic_string";
632 M_name_is_template = true;
633 M_name_is_cdtor = false;
634 M_name_is_conversion_operator = false;
638 qualifiers->printing_suppressed();
639 _GLIBCPP_DEMANGLER_RETURN;
642 output += "std::iostream";
643 if (!M_inside_template_args)
645 M_function_name = "iostream";
646 M_name_is_template = true;
647 M_name_is_cdtor = false;
648 M_name_is_conversion_operator = false;
652 qualifiers->printing_suppressed();
653 _GLIBCPP_DEMANGLER_RETURN;
655 output += "std::istream";
656 if (!M_inside_template_args)
658 M_function_name = "istream";
659 M_name_is_template = true;
660 M_name_is_cdtor = false;
661 M_name_is_conversion_operator = false;
665 qualifiers->printing_suppressed();
666 _GLIBCPP_DEMANGLER_RETURN;
668 output += "std::ostream";
669 if (!M_inside_template_args)
671 M_function_name = "ostream";
672 M_name_is_template = true;
673 M_name_is_cdtor = false;
674 M_name_is_conversion_operator = false;
678 qualifiers->printing_suppressed();
679 _GLIBCPP_DEMANGLER_RETURN;
681 output += "std::string";
682 if (!M_inside_template_args)
684 M_function_name = "string";
685 M_name_is_template = true;
686 M_name_is_cdtor = false;
687 M_name_is_conversion_operator = false;
691 qualifiers->printing_suppressed();
692 _GLIBCPP_DEMANGLER_RETURN;
697 qualifiers->printing_suppressed();
698 _GLIBCPP_DEMANGLER_RETURN;
703 value = value * 36 + c - '0';
705 value = value * 36 + c - 'A' + 10;
709 _GLIBCPP_DEMANGLER_FAILURE;
716 if (value >= M_substitutions_pos.size() ||
717 M_inside_type > 20) // Rather than core dump.
718 _GLIBCPP_DEMANGLER_FAILURE;
719 ++M_inside_substitution;
720 int saved_pos = M_pos;
721 substitution_st& substitution(M_substitutions_pos[value]);
722 M_pos = substitution.M_start_pos;
723 switch(substitution.M_type)
726 decode_type(output, qualifiers);
728 case template_template_param:
729 decode_template_param(output, qualifiers);
731 case nested_name_prefix:
732 case nested_name_template_prefix:
733 for (int cnt = substitution.M_number_of_prefixes; cnt > 0; --cnt)
735 if (current() == 'I')
737 if (M_template_args_need_space)
739 M_template_args_need_space = false;
740 if (!decode_template_args(output))
741 _GLIBCPP_DEMANGLER_FAILURE;
745 if (cnt < substitution.M_number_of_prefixes)
747 if (current() == 'S')
749 if (!decode_substitution(output))
750 _GLIBCPP_DEMANGLER_FAILURE;
752 else if (!decode_unqualified_name(output))
753 _GLIBCPP_DEMANGLER_FAILURE;
757 qualifiers->printing_suppressed();
759 case unscoped_template_name:
760 decode_unscoped_name(output);
762 qualifiers->printing_suppressed();
766 --M_inside_substitution;
767 _GLIBCPP_DEMANGLER_RETURN;
770 // <template-param> ::= T_ # first template parameter
771 // ::= T <parameter-2 non-negative number> _
773 template<typename Allocator>
775 session<Allocator>::decode_template_param(string_type& output,
776 qualifier_list<Allocator>* qualifiers)
778 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_template_parameter");
779 if (current() != 'T')
780 _GLIBCPP_DEMANGLER_FAILURE;
781 unsigned int value = 0;
783 if ((c = next()) != '_')
785 while(std::isdigit(c))
787 value = value * 10 + c - '0';
792 if (eat_current() != '_')
793 _GLIBCPP_DEMANGLER_FAILURE;
794 value += M_template_arg_pos_offset;
795 if (value >= M_template_arg_pos.size())
796 _GLIBCPP_DEMANGLER_FAILURE;
797 int saved_pos = M_pos;
798 M_pos = M_template_arg_pos[value];
799 if (M_inside_type > 20) // Rather than core dump.
800 _GLIBCPP_DEMANGLER_FAILURE;
801 ++M_inside_substitution;
802 if (current() == 'X')
805 decode_expression(output);
807 else if (current() == 'L')
808 decode_literal(output);
810 decode_type(output, qualifiers);
811 --M_inside_substitution;
813 _GLIBCPP_DEMANGLER_RETURN;
816 template<typename Allocator>
818 session<Allocator>::decode_literal(string_type& output)
820 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_literal");
821 eat_current(); // Eat the 'L'.
822 if (current() == '_')
825 _GLIBCPP_DEMANGLER_FAILURE;
827 if ((M_pos += decode_encoding(output, M_str + M_pos,
828 M_maxpos - M_pos + 1)) < 0)
829 _GLIBCPP_DEMANGLER_FAILURE;
834 if (current() == 'b')
841 _GLIBCPP_DEMANGLER_RETURN;
844 #ifdef _GLIBCPP_DEMANGLER_STYLE_LITERAL
845 if (c == 'i' || c == 'j' || c == 'l' ||
846 c == 'm' || c == 'x' || c == 'y')
850 #ifndef _GLIBCPP_DEMANGLER_STYLE_LITERAL_INT
858 if (!decode_type(output))
859 _GLIBCPP_DEMANGLER_FAILURE;
862 if (!decode_number(output))
863 _GLIBCPP_DEMANGLER_FAILURE;
864 #ifdef _GLIBCPP_DEMANGLER_STYLE_LITERAL
865 if (c == 'j' || c == 'm' || c == 'y')
867 if (c == 'l' || c == 'm')
869 if (c == 'x' || c == 'y')
873 _GLIBCPP_DEMANGLER_RETURN;
876 // <operator-name> ::=
924 // sr # scope resolution (::), see below
925 // cv <type> # (cast)
926 // v <digit> <source-name> # vendor extended operator
929 // Symbol operator codes exist of two characters, we need to find a
930 // quick hash so that their names can be looked up in a table.
933 // Shift the rows so that there is at most one character per column.
935 // A perfect solution:
937 // ..................................... offset + 'a'
938 // a, ||a||d|||||||||n||||s|||||||||||||||||| 2
939 // c, || || ||lm|o||| |||| |||||||||||||||||| -3
940 // d, || a| |e | ||l |||| |||v|||||||||||||| 3
941 // e, || | | o q| |||| ||| |||||||||||||| -4
942 // g, |e | | | t||| ||| |||||||||||||| -3
943 // i, | | | | ||| ||| ||||||||||x||| 12
944 // l, | | | e ||| ||| ||st|||||| ||| 9
945 // m, | | | ||| ||| |i lm|||| ||| 18
946 // n, a e g ||t |w| | |||| ||| 0
947 // o, || | | | ||o| r|| 19
948 // p, lm p | t || | || 6
952 // .....................................
953 // ^ ^__ second character
954 // |___ first character
957 // Putting that solution in tables:
959 char const offset_table_c [1 + CHAR_MAX - CHAR_MIN ] =
961 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
962 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
963 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
964 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
965 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
966 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
968 // Add -CHAR_MIN extra zeroes (128):
969 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
970 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
971 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
972 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
973 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
974 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
975 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
976 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
977 // a b c d e f g h i j k
978 0, -95, 0,-100, -94,-101, 0,-100, 0, -85, 0, 0,
979 // l m n o p q r s t u v
980 -88, -79, -97, -78, -91, -83, -77, -91, 0, 0, 0,
982 // a b c d e f g h i j k
983 0, 161, 0, 156, 162, 155, 0, 156, 0, 171, 0, 0,
984 // l m n o p q r s t u v
985 168, 177, 159, 178, 165, 173, 179, 165, 0, 0, 0,
993 char const* symbol_name;
997 entry_st const symbol_name_table_c[39] = {
998 { "na", "operator new[]", true },
999 { "ge", "operator>=", false },
1000 { "aa", "operator&&", false },
1001 { "da", "operator delete[]", true },
1002 { "ne", "operator!=", false },
1003 { "ad", "operator&", true }, // unary
1004 { "ng", "operator-", true }, // unary
1005 { "de", "operator*", true }, // unary
1006 { "cl", "operator()", true },
1007 { "cm", "operator,", false },
1008 { "eo=", "operator^", false },
1009 { "co", "operator~", false },
1010 { "eq", "operator==", false },
1011 { "le", "operator<=", false },
1012 { "dl", "operator delete", true },
1013 { "an=", "operator&", false },
1014 { "gt", "operator>", false },
1015 { "pl=", "operator+", false },
1016 { "pm", "operator->*", false },
1017 { "nt", "operator!", true },
1018 { "as=", "operator", false },
1019 { "pp", "operator++", true },
1020 { "nw", "operator new", true },
1021 { "sr", "::", true },
1022 { "dv=", "operator/", false },
1023 { "pt", "operator->", false },
1024 { "mi=", "operator-", false },
1025 { "ls=", "operator<<", false },
1026 { "lt", "operator<", false },
1027 { "ml=", "operator*", false },
1028 { "mm", "operator--", true },
1029 { "sz", "sizeof", true },
1030 { "rm=", "operator%", false },
1031 { "oo", "operator||", false },
1032 { "qu", "operator?", false },
1033 { "ix", "operator[]", true },
1034 { "or=", "operator|", false },
1035 { "", NULL, false },
1036 { "rs=", "operator>>", false }
1039 template<typename Allocator>
1041 session<Allocator>::decode_operator_name(string_type& output)
1043 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_operator_name");
1045 char opcode0 = current();
1046 char opcode1 = tolower(next());
1049 if ((hash = offset_table_c[opcode0 - CHAR_MIN]))
1058 int index = static_cast<int>(static_cast<unsigned char>(hash));
1059 entry_st entry = symbol_name_table_c[index];
1060 if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1061 && (opcode1 == current() || entry.opcode[2] == '='))
1063 output += entry.symbol_name;
1064 if (opcode1 != current())
1067 if (hash == 27 || hash == 28)
1068 M_template_args_need_space = true;
1069 _GLIBCPP_DEMANGLER_RETURN;
1071 else if (opcode0 == 'c' && opcode1 == 'v')
1074 output += "operator ";
1075 if (current() == 'T')
1077 // This is a templated cast operator.
1078 // It must be of the form "cvT_I...E".
1079 // Let M_template_arg_pos already point
1080 // to the template argument.
1081 M_template_arg_pos_offset = M_template_arg_pos.size();
1082 M_template_arg_pos.push_back(M_pos + 3);
1084 if (!decode_type(output))
1085 _GLIBCPP_DEMANGLER_FAILURE;
1086 if (!M_inside_template_args)
1087 M_name_is_conversion_operator = true;
1088 _GLIBCPP_DEMANGLER_RETURN;
1092 _GLIBCPP_DEMANGLER_FAILURE;
1096 // <expression> ::= <unary operator-name> <expression>
1097 // ::= <binary operator-name> <expression> <expression>
1098 // ::= <expr-primary>
1100 // <expr-primary> ::= <template-param> # Starts with a T
1101 // ::= L <type> <value number> E # literal
1102 // ::= L <mangled-name> E # external name
1104 template<typename Allocator>
1106 session<Allocator>::decode_expression(string_type& output)
1108 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_expression");
1109 if (current() == 'T')
1111 if (!decode_template_param(output))
1112 _GLIBCPP_DEMANGLER_FAILURE;
1113 _GLIBCPP_DEMANGLER_RETURN;
1115 else if (current() == 'L')
1117 if (!decode_literal(output))
1118 _GLIBCPP_DEMANGLER_FAILURE;
1119 if (current() != 'E')
1120 _GLIBCPP_DEMANGLER_FAILURE;
1122 _GLIBCPP_DEMANGLER_RETURN;
1126 char opcode0 = current();
1127 char opcode1 = tolower(next());
1130 if ((hash = offset_table_c[opcode0 - CHAR_MIN]))
1139 int index = static_cast<int>(static_cast<unsigned char>(hash));
1140 entry_st entry = symbol_name_table_c[index];
1141 if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1142 && (opcode1 == current() || entry.opcode[2] == '='))
1144 char const* p = entry.symbol_name;
1145 if (!strncmp("operator", p, 8))
1151 bool is_eq = (opcode1 != current());
1154 if (!decode_expression(output))
1155 _GLIBCPP_DEMANGLER_FAILURE;
1165 if (!decode_expression(output))
1166 _GLIBCPP_DEMANGLER_FAILURE;
1169 _GLIBCPP_DEMANGLER_RETURN;
1174 _GLIBCPP_DEMANGLER_FAILURE;
1178 // <template-args> ::= I <template-arg>+ E
1179 // <template-arg> ::= <type> # type or template
1180 // ::= L <type> <value number> E # literal
1181 // ::= L_Z <encoding> E # external name
1182 // ::= X <expression> E # expression
1183 template<typename Allocator>
1185 session<Allocator>::decode_template_args(string_type& output)
1187 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_template_args");
1188 if (eat_current() != 'I')
1189 _GLIBCPP_DEMANGLER_FAILURE;
1190 int prev_size = M_template_arg_pos.size();
1191 ++M_inside_template_args;
1192 if (M_template_args_need_space)
1195 M_template_args_need_space = false;
1200 if (M_inside_template_args == 1 && !M_inside_type)
1201 M_template_arg_pos.push_back(M_pos);
1202 if (current() == 'X')
1205 if (!decode_expression(output))
1206 _GLIBCPP_DEMANGLER_FAILURE;
1207 if (current() != 'E')
1208 _GLIBCPP_DEMANGLER_FAILURE;
1211 else if (current() == 'L')
1213 if (!decode_literal(output))
1214 _GLIBCPP_DEMANGLER_FAILURE;
1215 if (current() != 'E')
1216 _GLIBCPP_DEMANGLER_FAILURE;
1219 else if (!decode_type(output))
1220 _GLIBCPP_DEMANGLER_FAILURE;
1221 if (current() == 'E')
1226 if (*(output.rbegin()) == '>')
1229 --M_inside_template_args;
1230 if (!M_inside_template_args && !M_inside_type)
1232 M_name_is_template = true;
1233 M_template_arg_pos_offset = prev_size;
1235 _GLIBCPP_DEMANGLER_RETURN;
1238 // <bare-function-type> ::=
1239 // <signature type>+ # types are parameter types
1241 template<typename Allocator>
1243 session<Allocator>::decode_bare_function_type(string_type& output)
1245 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_bare_function_type");
1246 if (M_saw_destructor)
1248 if (eat_current() != 'v' || (current() != 'E' && current() != 0))
1249 _GLIBCPP_DEMANGLER_FAILURE;
1251 M_saw_destructor = false;
1252 _GLIBCPP_DEMANGLER_RETURN;
1254 #ifndef _GLIBCPP_DEMANGLER_STYLE_VOID
1255 if (current() == 'v')
1258 if (current() != 'E' && current() != 0)
1259 _GLIBCPP_DEMANGLER_FAILURE;
1261 M_saw_destructor = false;
1262 _GLIBCPP_DEMANGLER_RETURN;
1266 M_template_args_need_space = false;
1267 if (!decode_type(output)) // Must have at least one parameter.
1268 _GLIBCPP_DEMANGLER_FAILURE;
1269 while (current() != 'E' && current() != 0)
1272 if (!decode_type(output))
1273 _GLIBCPP_DEMANGLER_FAILURE;
1276 _GLIBCPP_DEMANGLER_RETURN;
1280 // <builtin-type> # Starts with a lower case character != r.
1281 // <function-type> # Starts with F
1282 // <class-enum-type> # Starts with N, S, C, D, Z, a digit or a lower
1283 // # case character. Since a lower case character
1284 // # would be an operator name, that would be an
1285 // # error. The S is a substitution or St
1286 // # (::std::). A 'C' would be a constructor and
1287 // # thus also an error.
1288 // <template-param> # Starts with T
1289 // <substitution> # Starts with S
1290 // <template-template-param> <template-args> # Starts with T or S,
1291 // # equivalent with the above.
1293 // <array-type> # Starts with A
1294 // <pointer-to-member-type> # Starts with M
1295 // <CV-qualifiers> <type> # Starts with r, V or K
1296 // P <type> # pointer-to # Starts with P
1297 // R <type> # reference-to # Starts with R
1298 // C <type> # complex (C 2000) # Starts with C
1299 // G <type> # imaginary (C 2000)# Starts with G
1300 // U <source-name> <type> # vendor extended type qualifier,
1303 // <template-template-param> ::= <template-param>
1304 // ::= <substitution>
1306 // My own analysis of how to decode qualifiers:
1308 // F is a <function-type>, <T> is a <builtin-type>, <class-enum-type>,
1309 // <template-param> or <template-template-param> <template-args>.
1310 // <Q> represents a series of qualifiers (not G or C).
1311 // <C> is an unqualified type.
1312 // <R> is a qualified type.
1313 // <B> is the bare-function-type without return type.
1314 // <I> is the array index.
1316 // <Q>M<C><Q2>F<R><B>E ==> R (C::*Q)B Q2 "<C>", "F<R><B>E"
1317 // (<R> and <B> recursive),
1318 // "M<C><Q2>F<R><B>E".
1319 // <Q>F<R><B>E ==> R (Q)B "<R>", "<B>" (<B> recursive)
1322 // Note that if <R> has postfix qualifiers (an array), then those
1323 // are added AFTER the (member) function type. For example:
1324 // <Q>FPA<R><B>E ==> R (*(Q)B) [], where the PA added the prefix
1325 // "(*" and the postfix ") []".
1327 // <Q>G<T> ==> imaginary T Q "<T>", "G<T>" (<T> recursive).
1328 // <Q>C<T> ==> complex T Q "<T>", "C<T>" (<T> recursive).
1329 // <Q><T> ==> T Q "<T>" (<T> recursive).
1331 // where <Q> is any of:
1333 // <Q>P ==> *Q "P..."
1334 // <Q>R ==> &Q "R..."
1335 // <Q>[K|V|r]+ ==> [ const| volatile| restrict]+Q "KVr..."
1336 // <Q>U<S> ==> SQ "U<S>..."
1337 // <Q>M<C> ==> C::*Q "M<C>..." (<C> recurs.)
1338 // A<I> ==> [I] "A<I>..." (<I> recurs.)
1339 // <Q>A<I> ==> (Q) [I] "A<I>..." (<I> recurs.)
1340 // Note that when <Q> ends on an A<I2> then the brackets are omitted:
1341 // A<I2>A<I> ==> [I2][I]
1343 // A <substitution> is handled with an input position switch during which
1344 // new substitutions are turned off. Because recursive handling of types
1345 // (and therefore the order in which substitutions must be generated) must
1346 // be done left to right, but the generation of Q needs processing right to
1347 // left, substitutions per <type> are generated by reading the input left
1348 // to right and marking the starts of all substitutions only - implicitly
1349 // finishing them at the end of the type. Then the output and real
1350 // substitutions are generated.
1352 // The following comment was for the demangling of g++ version 3.0.x. The
1353 // mangling (and I believe even the ABI description) have been fixed now
1354 // (as of g++ version 3.1).
1357 // The ABI specifies for pointer-to-member function types the format
1358 // <Q>M<T>F<R><B>E. In other words, the qualifier <Q2> (see above) is
1359 // implicitely contained in <T> instead of explicitly part of the M format.
1360 // I am convinced that this is a bug in the ABI. Unfortunately, this is
1361 // how we have to demangle things as it has a direct impact on the order
1362 // in which substitutions are stored. This ill-formed design results in
1363 // rather ill-formed demangler code too however :/
1365 // <Q2> is now explicitely part of the M format.
1366 // For some weird reason, g++ (3.2.1) does not add substitutions for
1367 // qualified member function pointers. I think that is another bug.
1369 template<typename Allocator>
1371 qualifier_list<Allocator>::decode_qualifiers(
1372 string_type& prefix,
1373 string_type& postfix,
1374 bool member_function_pointer_qualifiers = false)
1376 for(typename std::vector<qualifier<Allocator>, Allocator>::
1377 reverse_iterator iter = M_qualifier_starts.rbegin();
1378 iter != M_qualifier_starts.rend();)
1380 if (!member_function_pointer_qualifiers
1381 && !(*iter).part_of_substitution())
1383 int saved_inside_substitution = M_demangler.M_inside_substitution;
1384 M_demangler.M_inside_substitution = 0;
1385 M_demangler.add_substitution((*iter).get_start_pos(), type);
1386 M_demangler.M_inside_substitution = saved_inside_substitution;
1388 char qualifier_char = (*iter).first_qualifier();
1389 for(; qualifier_char; qualifier_char = (*iter).next_qualifier())
1391 switch(qualifier_char)
1403 prefix += " volatile";
1406 prefix += " restrict";
1410 string_type index = (*iter).get_optional_type();
1411 if (++iter != M_qualifier_starts.rend()
1412 && (*iter).first_qualifier() != 'A')
1415 postfix = ") [" + index + "]" + postfix;
1418 postfix = "[" + index + "]" + postfix;
1423 prefix += (*iter).get_optional_type();
1428 prefix += (*iter).get_optional_type();
1430 case 'G': // Only here so we added a substitution.
1435 if (qualifier_char != 'A')
1438 M_printing_suppressed = false;
1442 template<typename Allocator>
1444 session<Allocator>::decode_type_with_postfix(
1445 string_type& prefix, string_type& postfix,
1446 qualifier_list<Allocator>* qualifiers)
1448 _GLIBCPP_DEMANGLER_DOUT_ENTERING2
1449 (qualifiers ? "decode_type" : "decode_type[with qualifiers]");
1451 bool recursive_template_param_or_substitution_call;
1452 if (!(recursive_template_param_or_substitution_call = qualifiers))
1453 qualifiers = new qualifier_list<Allocator>(*this);
1454 // First eat all qualifiers.
1455 bool failure = false;
1456 for(;;) // So we can use 'continue' to eat the next qualifier.
1458 int start_pos = M_pos;
1462 qualifiers->add_qualifier_start(pointer, start_pos,
1463 M_inside_substitution);
1467 qualifiers->add_qualifier_start(reference, start_pos,
1468 M_inside_substitution);
1482 while(c == 'K' || c == 'V' || c == 'r');
1483 qualifiers->add_qualifier_start(cv_qualifier, start_pos, count,
1484 M_inside_substitution);
1490 string_type source_name;
1491 if (!decode_source_name(source_name))
1496 qualifiers->add_qualifier_start(vendor_extension, start_pos,
1497 source_name, M_inside_substitution);
1502 // <array-type> ::= A <positive dimension number> _ <element type>
1503 // ::= A [<dimension expression>] _ <element type>
1508 if (next() == 'n' || !decode_number(index))
1511 if (next() != '_' && !decode_expression(index))
1517 if (eat_current() != '_')
1522 qualifiers->add_qualifier_start(array, start_pos, index,
1523 M_inside_substitution);
1528 // <Q>M<C> or <Q>M<C><Q2>F<R><B>E
1530 string_type class_type;
1531 if (!decode_type(class_type)) // Substitution: "<C>".
1537 if (c == 'F' || c == 'K' || c == 'V' || c == 'r')
1538 // Must be CV-qualifiers and a member function pointer.
1540 // <Q>M<C><Q2>F<R><B>E ==> R (C::*Q)B Q2
1541 // substitutions: "<C>", "F<R><B>E" (<R> and <B>
1542 // recursive), "M<C><Q2>F<R><B>E".
1544 int Q2_start_pos = M_pos;
1545 while(c == 'K' || c == 'V' || c == 'r') // Decode <Q2>.
1550 qualifier_list<Allocator> class_type_qualifiers(*this);
1552 class_type_qualifiers.
1553 add_qualifier_start(cv_qualifier, Q2_start_pos,
1554 count, M_inside_substitution);
1555 string_type member_function_qualifiers;
1556 // It is unclear why g++ doesn't add a substitution for
1557 // "<Q2>F<R><B>E" as it should I think.
1558 string_type member_function_qualifiers_postfix;
1559 class_type_qualifiers.
1560 decode_qualifiers(member_function_qualifiers,
1561 member_function_qualifiers_postfix, true);
1562 member_function_qualifiers +=
1563 member_function_qualifiers_postfix;
1564 // I don't think this substitution is actually ever used.
1565 int function_pos = M_pos;
1566 if (eat_current() != 'F')
1572 // Constructors, destructors and conversion operators don't
1573 // have a return type, but seem to never get here.
1574 if (!decode_type_with_postfix(prefix, postfix))
1575 // substitution: <R> recursive
1581 prefix += class_type;
1583 string_type bare_function_type;
1584 if (!decode_bare_function_type(bare_function_type)
1585 || eat_current() != 'E') // Substitution: <B> recursive.
1590 // substitution: "F<R><B>E".
1591 add_substitution(function_pos, type);
1592 // substitution: "M<C><Q2>F<R><B>E".
1593 add_substitution(start_pos, type);
1594 // substitution: all qualified types if any.
1595 qualifiers->decode_qualifiers(prefix, postfix);
1597 prefix += bare_function_type;
1598 prefix += member_function_qualifiers;
1599 goto decode_type_exit;
1601 qualifiers->add_qualifier_start(pointer_to_member, start_pos,
1602 class_type, M_inside_substitution);
1612 // <Q>G<T> ==> imaginary T Q
1613 // substitutions: "<T>", "G<T>" (<T> recursive).
1614 // <Q>C<T> ==> complex T Q
1615 // substitutions: "<T>", "C<T>" (<T> recursive).
1616 if (current() == 'C' || current() == 'G')
1618 prefix += current() == 'C' ? "complex " : "imaginary ";
1619 qualifiers->add_qualifier_start(complex_or_imaginary, M_pos,
1620 M_inside_substitution);
1623 int start_pos = M_pos;
1628 // <Q>F<R><B>E ==> R (Q)B
1629 // substitution: "<R>", "<B>" (<B> recursive) and "F<R><B>E".
1632 if (!decode_type_with_postfix(prefix, postfix))
1633 // Substitution: "<R>".
1638 // Only array (pointer) types have a postfix.
1639 // In that case we don't want the space but
1640 // expect something like prefix is "int (*"
1641 // and postfix is ") [1]".
1642 if (postfix.size() == 0)
1645 string_type bare_function_type;
1646 if (!decode_bare_function_type(bare_function_type)
1647 // substitution: "<B>" (<B> recursive).
1648 || eat_current() != 'E')
1653 add_substitution(start_pos, type); // Substitution: "F<R><B>E".
1654 qualifiers->decode_qualifiers(prefix, postfix);
1655 // substitution: all qualified types, if any.
1657 prefix += bare_function_type;
1661 if (!decode_template_param(prefix, qualifiers))
1666 if (current() == 'I')
1668 add_substitution(start_pos, template_template_param);
1669 // substitution: "<template-template-param>".
1670 if (!decode_template_args(prefix))
1676 if (!recursive_template_param_or_substitution_call
1677 && qualifiers->suppressed())
1679 add_substitution(start_pos, type);
1680 // substitution: "<template-param>" or
1681 // "<template-template-param> <template-args>".
1682 qualifiers->decode_qualifiers(prefix, postfix);
1683 // substitution: all qualified types, if any.
1687 if (M_pos >= M_maxpos)
1692 if (M_str[M_pos + 1] != 't')
1694 if (!decode_substitution(prefix, qualifiers))
1699 if (current() == 'I')
1701 if (!decode_template_args(prefix))
1706 if (!recursive_template_param_or_substitution_call
1707 && qualifiers->suppressed())
1708 add_substitution(start_pos, type);
1710 // "<template-template-param> <template-args>".
1712 if (!recursive_template_param_or_substitution_call
1713 && qualifiers->suppressed())
1714 qualifiers->decode_qualifiers(prefix, postfix);
1715 // Substitution: all qualified types, if any.
1718 /* Fall-through for St */
1732 // substitutions: "<T>" (<T> recursive).
1733 if (!decode_class_enum_type(prefix))
1738 if (!recursive_template_param_or_substitution_call)
1740 add_substitution(start_pos, type);
1741 // substitution: "<class-enum-type>".
1742 qualifiers->decode_qualifiers(prefix, postfix);
1743 // substitution: all qualified types, if any.
1746 qualifiers->printing_suppressed();
1750 // substitutions: "<T>" (<T> recursive).
1751 if (!decode_builtin_type(prefix))
1756 // If decode_type was called from decode_template_param then we
1757 // need to suppress calling qualifiers here in order to get a
1758 // substitution added anyway (for the <template-param>).
1759 if (!recursive_template_param_or_substitution_call)
1760 qualifiers->decode_qualifiers(prefix, postfix);
1762 qualifiers->printing_suppressed();
1768 if (!recursive_template_param_or_substitution_call)
1771 _GLIBCPP_DEMANGLER_FAILURE;
1772 _GLIBCPP_DEMANGLER_RETURN2;
1775 // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
1776 // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
1778 // <prefix> ::= <prefix> <unqualified-name>
1779 // ::= <template-prefix> <template-args>
1781 // ::= <substitution>
1783 // <template-prefix> ::= <prefix> <template unqualified-name>
1784 // ::= <substitution>
1786 template<typename Allocator>
1788 session<Allocator>::decode_nested_name(string_type& output,
1789 string_type& qualifiers)
1791 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_nested_name");
1793 if (current() != 'N' || M_pos >= M_maxpos)
1794 _GLIBCPP_DEMANGLER_FAILURE;
1796 // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const
1797 char const* qualifiers_start = &M_str[M_pos + 1];
1798 for (char c = next(); c == 'K' || c == 'V' || c == 'r'; c = next());
1799 for (char const* qualifier_ptr = &M_str[M_pos - 1];
1800 qualifier_ptr >= qualifiers_start; --qualifier_ptr)
1801 switch(*qualifier_ptr)
1804 qualifiers += " const";
1807 qualifiers += " volatile";
1810 qualifiers += " restrict";
1814 int number_of_prefixes = 0;
1815 int substitution_start = M_pos;
1818 ++number_of_prefixes;
1819 if (current() == 'S')
1821 if (!decode_substitution(output))
1822 _GLIBCPP_DEMANGLER_FAILURE;
1824 else if (current() == 'I')
1826 if (!decode_template_args(output))
1827 _GLIBCPP_DEMANGLER_FAILURE;
1828 if (current() != 'E')
1830 // substitution: "<template-prefix> <template-args>".
1831 add_substitution(substitution_start, nested_name_prefix,
1832 number_of_prefixes);
1837 if (!decode_unqualified_name(output))
1838 _GLIBCPP_DEMANGLER_FAILURE;
1839 if (current() != 'E')
1841 // substitution: "<prefix> <unqualified-name>" or
1842 // "<prefix> <template unqualified-name>".
1843 add_substitution(substitution_start,
1844 (current() == 'I') ? nested_name_template_prefix
1845 : nested_name_prefix,
1846 number_of_prefixes);
1849 if (current() == 'E')
1852 _GLIBCPP_DEMANGLER_RETURN;
1854 if (current() != 'I')
1856 else if (M_template_args_need_space)
1858 M_template_args_need_space = false;
1860 _GLIBCPP_DEMANGLER_FAILURE;
1863 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
1864 // := Z <function encoding> E s [<discriminator>]
1865 // <discriminator> := _ <non-negative number>
1867 template<typename Allocator>
1869 session<Allocator>::decode_local_name(string_type& output)
1871 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_local_name");
1872 if (current() != 'Z' || M_pos >= M_maxpos)
1873 _GLIBCPP_DEMANGLER_FAILURE;
1874 if ((M_pos += decode_encoding(output, M_str + M_pos + 1,
1875 M_maxpos - M_pos) + 1) < 0 || eat_current() != 'E')
1876 _GLIBCPP_DEMANGLER_FAILURE;
1878 if (current() == 's')
1881 output += "string literal";
1885 string_type nested_name_qualifiers;
1886 if (!decode_name(output, nested_name_qualifiers))
1887 _GLIBCPP_DEMANGLER_FAILURE;
1888 output += nested_name_qualifiers;
1890 string_type discriminator;
1891 if (current() == '_' && next() != 'n' && !decode_number(discriminator))
1892 _GLIBCPP_DEMANGLER_FAILURE;
1893 _GLIBCPP_DEMANGLER_RETURN;
1896 // <source-name> ::= <positive length number> <identifier>
1898 template<typename Allocator>
1900 session<Allocator>::decode_source_name(string_type& output)
1902 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_source_name");
1903 int length = current() - '0';
1904 if (length < 1 || length > 9)
1905 _GLIBCPP_DEMANGLER_FAILURE;
1906 while(std::isdigit(next()))
1907 length = 10 * length + current() - '0';
1908 char const* ptr = &M_str[M_pos];
1909 if (length > 11 && !strncmp(ptr, "_GLOBAL_", 8) && ptr[9] == 'N'
1910 && ptr[8] == ptr[10])
1912 output += "(anonymous namespace)";
1913 if ((M_pos += length) > M_maxpos + 1)
1914 _GLIBCPP_DEMANGLER_FAILURE;
1920 _GLIBCPP_DEMANGLER_FAILURE;
1921 output += eat_current();
1923 _GLIBCPP_DEMANGLER_RETURN;
1926 // <unqualified-name> ::= <operator-name> # Starts with lower case.
1927 // ::= <ctor-dtor-name> # Starts with 'C' or 'D'.
1928 // ::= <source-name> # Starts with a digit.
1930 template<typename Allocator>
1932 session<Allocator>::decode_unqualified_name(string_type& output)
1934 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_unqualified_name");
1935 if (std::isdigit(current()))
1937 if (!M_inside_template_args)
1939 bool recursive_unqualified_name = (&M_function_name == &output);
1940 // This can be a recursive call when we are decoding
1941 // an <operator-name> that is a cast operator for a some
1942 // <unqualified-name>; for example "operator Foo()".
1943 // In that case this is thus not a ctor or dtor and we
1944 // are not interested in updating M_function_name.
1945 if (!recursive_unqualified_name)
1946 M_function_name.clear();
1947 M_name_is_template = false;
1948 M_name_is_cdtor = false;
1949 M_name_is_conversion_operator = false;
1950 if (!decode_source_name(M_function_name))
1951 _GLIBCPP_DEMANGLER_FAILURE;
1952 if (!recursive_unqualified_name)
1953 output += M_function_name;
1955 else if (!decode_source_name(output))
1956 _GLIBCPP_DEMANGLER_FAILURE;
1957 _GLIBCPP_DEMANGLER_RETURN;
1959 if (islower(current()))
1961 if (!M_inside_template_args)
1963 M_function_name.clear();
1964 M_name_is_template = false;
1965 M_name_is_cdtor = false;
1966 M_name_is_conversion_operator = false;
1967 if (!decode_operator_name(M_function_name))
1968 _GLIBCPP_DEMANGLER_FAILURE;
1969 output += M_function_name;
1971 _GLIBCPP_DEMANGLER_RETURN;
1973 if (current() == 'C' || current() == 'D')
1975 if (M_inside_template_args)
1976 _GLIBCPP_DEMANGLER_FAILURE;
1977 // <ctor-dtor-name> ::=
1978 // C1 # complete object (in-charge) constructor
1979 // C2 # base object (not-in-charge) constructor
1980 // C3 # complete object (in-charge) allocating constructor
1981 // D0 # deleting (in-charge) destructor
1982 // D1 # complete object (in-charge) destructor
1983 // D2 # base object (not-in-charge) destructor
1985 if (current() == 'C')
1988 if (c < '1' || c > '3')
1989 _GLIBCPP_DEMANGLER_FAILURE;
1994 if (c < '0' || c > '2')
1995 _GLIBCPP_DEMANGLER_FAILURE;
1997 M_saw_destructor = true;
1999 M_name_is_cdtor = true;
2001 output += M_function_name;
2002 _GLIBCPP_DEMANGLER_RETURN;
2004 _GLIBCPP_DEMANGLER_FAILURE;
2007 // <unscoped-name> ::=
2008 // <unqualified-name> # Starts not with an 'S'
2009 // St <unqualified-name> # ::std::
2011 template<typename Allocator>
2013 session<Allocator>::decode_unscoped_name(string_type& output)
2015 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_unscoped_name");
2016 if (current() == 'S')
2019 _GLIBCPP_DEMANGLER_FAILURE;
2023 decode_unqualified_name(output);
2024 _GLIBCPP_DEMANGLER_RETURN;
2028 // <nested-name> # Starts with 'N'
2029 // <unscoped-template-name> <template-args> # idem
2030 // <local-name> # Starts with 'Z'
2031 // <unscoped-name> # Starts with 'S', 'C', 'D',
2032 // # a digit or a lower case
2035 // <unscoped-template-name> ::= <unscoped-name>
2036 // ::= <substitution>
2037 template<typename Allocator>
2039 session<Allocator>::decode_name(string_type& output,
2040 string_type& nested_name_qualifiers)
2042 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_name");
2043 int substitution_start = M_pos;
2044 if (current() == 'S' && (M_pos >= M_maxpos || M_str[M_pos + 1] != 't'))
2046 if (!decode_substitution(output))
2047 _GLIBCPP_DEMANGLER_FAILURE;
2049 else if (current() == 'N')
2051 decode_nested_name(output, nested_name_qualifiers);
2052 _GLIBCPP_DEMANGLER_RETURN;
2054 else if (current() == 'Z')
2056 decode_local_name(output);
2057 _GLIBCPP_DEMANGLER_RETURN;
2059 else if (!decode_unscoped_name(output))
2060 _GLIBCPP_DEMANGLER_FAILURE;
2061 if (current() == 'I')
2063 // Must have been an <unscoped-template-name>.
2064 add_substitution(substitution_start, unscoped_template_name);
2065 if (!decode_template_args(output))
2066 _GLIBCPP_DEMANGLER_FAILURE;
2068 M_template_args_need_space = false;
2069 _GLIBCPP_DEMANGLER_RETURN;
2072 // <call-offset> ::= h <nv-offset> _
2073 // ::= v <v-offset> _
2074 // <nv-offset> ::= <offset number>
2075 // non-virtual base override
2077 // <v-offset> ::= <offset number> _ <virtual offset number>
2078 // virtual base override, with vcall offset
2079 template<typename Allocator>
2081 session<Allocator>::decode_call_offset(string_type&
2082 #if _GLIBCPP_DEMANGLER_CWDEBUG
2087 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_call_offset");
2088 if (current() == 'h')
2092 if (decode_number(dummy) && current() == '_')
2095 _GLIBCPP_DEMANGLER_RETURN;
2098 else if (current() == 'v')
2102 if (decode_number(dummy) && current() == '_')
2105 if (decode_number(dummy) && current() == '_')
2108 _GLIBCPP_DEMANGLER_RETURN;
2112 _GLIBCPP_DEMANGLER_FAILURE;
2116 // <special-name> ::=
2117 // TV <type> # virtual table
2118 // TT <type> # VTT structure (construction
2120 // TI <type> # typeinfo structure
2121 // TS <type> # typeinfo name (null-terminated
2123 // GV <object name> # Guard variable for one-time
2124 // initialization of static objects in
2126 // T <call-offset> <base encoding># base is the nominal target function
2128 // Tc <call-offset> <call-offset> <base encoding> # base is the nominal
2129 // target function of thunk; first
2130 // call-offset is 'this' adjustment;
2131 // second call-offset is result
2134 template<typename Allocator>
2136 session<Allocator>::decode_special_name(string_type& output)
2138 _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_special_name");
2139 if (current() == 'G')
2142 _GLIBCPP_DEMANGLER_FAILURE;
2143 output += "guard variable for ";
2144 string_type nested_name_qualifiers;
2146 if (!decode_name(output, nested_name_qualifiers))
2147 _GLIBCPP_DEMANGLER_FAILURE;
2148 output += nested_name_qualifiers;
2149 _GLIBCPP_DEMANGLER_RETURN;
2151 else if (current() != 'T')
2152 _GLIBCPP_DEMANGLER_FAILURE;
2156 output += "vtable for ";
2158 decode_type(output);
2159 _GLIBCPP_DEMANGLER_RETURN;
2161 output += "VTT for ";
2163 decode_type(output);
2164 _GLIBCPP_DEMANGLER_RETURN;
2166 output += "typeinfo for ";
2168 decode_type(output);
2169 _GLIBCPP_DEMANGLER_RETURN;
2171 output += "typeinfo name for ";
2173 decode_type(output);
2174 _GLIBCPP_DEMANGLER_RETURN;
2176 output += "covariant return thunk to ";
2177 if (!decode_call_offset(output)
2178 || !decode_call_offset(output)
2179 || (M_pos += decode_encoding(output, M_str + M_pos,
2180 M_maxpos - M_pos + 1)) < 0)
2181 _GLIBCPP_DEMANGLER_FAILURE;
2182 _GLIBCPP_DEMANGLER_RETURN;
2183 case 'C': // GNU extension?
2186 output += "construction vtable for ";
2188 if (!decode_type(first))
2189 _GLIBCPP_DEMANGLER_FAILURE;
2190 while(std::isdigit(current()))
2192 if (eat_current() != '_')
2193 _GLIBCPP_DEMANGLER_FAILURE;
2194 if (!decode_type(output))
2195 _GLIBCPP_DEMANGLER_FAILURE;
2198 _GLIBCPP_DEMANGLER_RETURN;
2201 if (current() == 'v')
2202 output += "virtual thunk to ";
2204 output += "non-virtual thunk to ";
2205 if (!decode_call_offset(output)
2206 || (M_pos += decode_encoding(output, M_str + M_pos,
2207 M_maxpos - M_pos + 1)) < 0)
2208 _GLIBCPP_DEMANGLER_FAILURE;
2209 _GLIBCPP_DEMANGLER_RETURN;
2214 // <function name> <bare-function-type> # Starts with 'C', 'D', 'N',
2215 // 'S', a digit or a lower case
2217 // <data name> # Idem.
2218 // <special-name> # Starts with 'T' or 'G'.
2219 template<typename Allocator>
2221 session<Allocator>::decode_encoding(string_type& output,
2225 #if _GLIBCPP_DEMANGLER_CWDEBUG
2226 _GLIBCPP_DEMANGLER_DOUT(dc::demangler,
2227 "Output thus far: \"" << output << '"');
2228 string_type input(in, len > 0x40000000 ? strlen(in) : len);
2229 _GLIBCPP_DEMANGLER_DOUT(
2230 dc::demangler, "Entering decode_encoding(\"" << input << "\")");
2234 session<Allocator> demangler_session(in, len);
2235 string_type nested_name_qualifiers;
2237 demangler_session.store(saved_pos);
2238 if (demangler_session.decode_special_name(output))
2239 return demangler_session.M_pos;
2240 demangler_session.restore(saved_pos);
2242 if (!demangler_session.decode_name(name, nested_name_qualifiers))
2244 if (demangler_session.current() == 0
2245 || demangler_session.current() == 'E')
2248 output += nested_name_qualifiers;
2249 return demangler_session.M_pos;
2251 // Must have been a <function name>.
2252 if (demangler_session.M_name_is_template
2253 && !(demangler_session.M_name_is_cdtor
2254 || demangler_session.M_name_is_conversion_operator))
2256 if (!demangler_session.decode_type(output))
2257 // Return type of function
2262 if (!demangler_session.decode_bare_function_type(output))
2264 output += nested_name_qualifiers;
2265 return demangler_session.M_pos;
2268 } // namespace demangler
2271 template<typename Allocator>
2274 typedef Allocator allocator_type;
2275 typedef std::basic_string<char, std::char_traits<char>, Allocator>
2277 static string_type symbol(char const* in);
2278 static string_type type(char const* in);
2281 // demangle::symbol()
2283 // Demangle `input' which should be a mangled function name as for
2284 // instance returned by nm(1).
2285 template<typename Allocator>
2286 std::basic_string<char, std::char_traits<char>, Allocator>
2287 demangle<Allocator>::symbol(char const* input)
2289 // <mangled-name> ::= _Z <encoding>
2290 // <mangled-name> ::= _GLOBAL_ _<type>_ _Z <encoding>
2291 // <type> can be I or D (GNU extension)
2292 typedef demangler::session<Allocator> demangler_type;
2294 bool failure = (input[0] != '_');
2298 if (input[1] == 'G')
2300 if (!strncmp(input, "_GLOBAL__", 9)
2301 && (input[9] == 'D' || input[9] == 'I')
2302 && input[10] == '_' && input[11] == '_' && input[12] == 'Z')
2304 if (input[9] == 'D')
2305 result.assign("global destructors keyed to ", 28);
2307 result.assign("global constructors keyed to ", 29);
2308 int cnt = demangler_type::decode_encoding(result, input + 13,
2310 if (cnt < 0 || input[cnt + 13] != 0)
2316 else if (input[1] == 'Z')
2318 int cnt = demangler_type::decode_encoding(result, input + 2,
2320 if (cnt < 0 || input[cnt + 2] != 0)
2327 // Failure to demangle, return the mangled name.
2329 result.assign(input, strlen(input));
2335 // Demangle `input' which must be a zero terminated mangled type
2336 // name as for instance returned by std::type_info::name().
2337 template<typename Allocator>
2338 std::basic_string<char, std::char_traits<char>, Allocator>
2339 demangle<Allocator>::type(char const* input)
2341 std::basic_string<char, std::char_traits<char>, Allocator> result;
2346 demangler::session<Allocator> demangler_session(input, INT_MAX);
2347 if (!demangler_session.decode_type(result)
2348 || demangler_session.remaining_input_characters())
2350 // Failure to demangle, return the mangled name.
2357 } // namespace __gnu_cxx
2359 #endif // __DEMANGLE_H