2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libstdc++-v3 / include / bits / demangle.h
blob2c240162e90e9e4403ae63499d5234d1a9d58ff0
1 // C++ IA64 / g++ v3 demangler -*- C++ -*-
3 // Copyright (C) 2003 Free Software Foundation, Inc.
4 // Written by Carlo Wood <carlo@alinoe.com>
5 //
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)
10 // any later version.
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,
20 // USA.
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.
31 // This file implements demangling of "C++ ABI for Itanium"-mangled symbol
32 // and type names as described in Revision 1.73 of the C++ ABI as can be found
33 // at http://www.codesourcery.com/cxx-abi/abi.html#mangling
35 #ifndef _DEMANGLER_H
36 #define _DEMANGLER_H 1
38 #include <vector>
39 #include <string>
41 #ifndef _GLIBCXX_DEMANGLER_DEBUG
42 #define _GLIBCXX_DEMANGLER_CWDEBUG 0
43 #define _GLIBCXX_DEMANGLER_DEBUG(x)
44 #define _GLIBCXX_DEMANGLER_DOUT(cntrl, data)
45 #define _GLIBCXX_DEMANGLER_DOUT_ENTERING(x)
46 #define _GLIBCXX_DEMANGLER_DOUT_ENTERING2(x)
47 #define _GLIBCXX_DEMANGLER_DOUT_ENTERING3(x)
48 #define _GLIBCXX_DEMANGLER_RETURN return M_result
49 #define _GLIBCXX_DEMANGLER_RETURN2 return M_result
50 #define _GLIBCXX_DEMANGLER_RETURN3
51 #define _GLIBCXX_DEMANGLER_FAILURE \
52 do { M_result = false; return false; } while(0)
53 #else
54 #define _GLIBCXX_DEMANGLER_CWDEBUG 1
55 #endif
57 namespace __gnu_cxx
59 namespace demangler
62 enum substitution_nt
64 type,
65 template_template_param,
66 nested_name_prefix,
67 nested_name_template_prefix,
68 unscoped_template_name
71 struct substitution_st
73 int M_start_pos;
74 substitution_nt M_type;
75 int M_number_of_prefixes;
77 substitution_st(int start_pos,
78 substitution_nt type,
79 int number_of_prefixes)
80 : M_start_pos(start_pos), M_type(type),
81 M_number_of_prefixes(number_of_prefixes)
82 { }
85 enum simple_qualifier_nt
87 complex_or_imaginary = 'G',
88 pointer = 'P',
89 reference = 'R'
92 enum cv_qualifier_nt
94 cv_qualifier = 'K'
97 enum param_qualifier_nt
99 vendor_extension = 'U',
100 array = 'A',
101 pointer_to_member = 'M'
104 template<typename Allocator>
105 class qualifier;
107 template<typename Allocator>
108 class qualifier_list;
110 template<typename Allocator>
111 class session;
113 template<typename Allocator>
114 class qualifier
116 typedef typename Allocator::template rebind<char>::other
117 char_Allocator;
118 typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
119 string_type;
121 private:
122 char M_qualifier1;
123 char M_qualifier2;
124 char M_qualifier3;
125 mutable unsigned char M_cnt;
126 string_type M_optional_type;
127 int M_start_pos;
128 bool M_part_of_substitution;
130 public:
131 qualifier(int start_pos,
132 simple_qualifier_nt simple_qualifier,
133 int inside_substitution)
134 : M_qualifier1(simple_qualifier),
135 M_start_pos(start_pos),
136 M_part_of_substitution(inside_substitution)
139 qualifier(int start_pos,
140 cv_qualifier_nt,
141 char const* start,
142 int count,
143 int inside_substitution)
144 : M_qualifier1(start[0]),
145 M_qualifier2((count > 1) ? start[1] : '\0'),
146 M_qualifier3((count > 2) ? start[2] : '\0'),
147 M_start_pos(start_pos),
148 M_part_of_substitution(inside_substitution)
151 qualifier(int start_pos,
152 param_qualifier_nt param_qualifier,
153 string_type optional_type,
154 int inside_substitution)
155 : M_qualifier1(param_qualifier),
156 M_optional_type(optional_type),
157 M_start_pos(start_pos),
158 M_part_of_substitution(inside_substitution)
162 get_start_pos(void) const
163 { return M_start_pos; }
165 char
166 first_qualifier(void) const
167 { M_cnt = 1; return M_qualifier1; }
169 char
170 next_qualifier(void) const
172 return (++M_cnt == 2) ? M_qualifier2
173 : ((M_cnt == 3) ? M_qualifier3 : 0);
176 string_type const&
177 get_optional_type(void) const
178 { return M_optional_type; }
180 bool
181 part_of_substitution(void) const
182 { return M_part_of_substitution; }
184 #if _GLIBCXX_DEMANGLER_CWDEBUG
185 friend std::ostream& operator<<(std::ostream& os, qualifier const& qual)
187 os << (char)qual.M_qualifier1;
188 if (qual.M_qualifier1 == vendor_extension ||
189 qual.M_qualifier1 == array ||
190 qual.M_qualifier1 == pointer_to_member)
191 os << " [" << qual.M_optional_type << ']';
192 else if (qual.M_qualifier1 == 'K' ||
193 qual.M_qualifier1 == 'V' ||
194 qual.M_qualifier1 == 'r')
196 if (qual.M_qualifier2)
198 os << (char)qual.M_qualifier2;
199 if (qual.M_qualifier3)
200 os << (char)qual.M_qualifier3;
203 return os;
205 #endif
208 template<typename Allocator>
209 class qualifier_list
211 typedef typename Allocator::template rebind<char>::other
212 char_Allocator;
213 typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
214 string_type;
216 private:
217 mutable bool M_printing_suppressed;
218 typedef qualifier<Allocator> qual;
219 typedef typename Allocator::template rebind<qual>::other qual_Allocator;
220 typedef std::vector<qual, qual_Allocator> qual_vector;
221 qual_vector M_qualifier_starts;
222 session<Allocator>& M_demangler;
224 void decode_KVrA(string_type& prefix, string_type& postfix, int cvq,
225 typename qual_vector::
226 const_reverse_iterator const& iter_array) const;
228 public:
229 qualifier_list(session<Allocator>& demangler_obj)
230 : M_printing_suppressed(false), M_demangler(demangler_obj)
233 void
234 add_qualifier_start(simple_qualifier_nt simple_qualifier,
235 int start_pos,
236 int inside_substitution)
237 { M_qualifier_starts.
238 push_back(qualifier<Allocator>(start_pos,
239 simple_qualifier, inside_substitution)); }
241 void
242 add_qualifier_start(cv_qualifier_nt cv_qualifier,
243 int start_pos,
244 int count,
245 int inside_substitution)
246 { M_qualifier_starts.
247 push_back(qualifier<Allocator>(start_pos,
248 cv_qualifier, &M_demangler.M_str[start_pos],
249 count, inside_substitution)); }
251 void
252 add_qualifier_start(param_qualifier_nt param_qualifier,
253 int start_pos,
254 string_type optional_type,
255 int inside_substitution)
256 { M_qualifier_starts.
257 push_back(qualifier<Allocator>(start_pos,
258 param_qualifier, optional_type, inside_substitution)); }
260 void
261 decode_qualifiers(string_type& prefix,
262 string_type& postfix,
263 bool member_function_pointer_qualifiers) const;
265 bool
266 suppressed(void) const
267 { return M_printing_suppressed; }
269 void
270 printing_suppressed(void)
271 { M_printing_suppressed = true; }
273 size_t
274 size(void) const
275 { return M_qualifier_starts.size(); }
277 #if _GLIBCXX_DEMANGLER_CWDEBUG
278 friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list)
280 typename qual_vector::const_iterator
281 iter = list.M_qualifier_starts.begin();
282 if (iter != list.M_qualifier_starts.end())
284 os << "{ " << *iter;
285 while (++iter != list.M_qualifier_starts.end())
286 os << ", " << *iter;
287 os << " }";
289 else
290 os << "{ }";
291 return os;
293 #endif
296 struct implementation_details
298 private:
299 unsigned int M_style;
301 public:
302 // The following flags change the behaviour of the demangler. The
303 // default behaviour is that none of these flags is set.
305 static unsigned int const style_void = 1;
306 // Default behaviour: int f()
307 // Use (void) instead of (): int f(void)
309 static unsigned int const style_literal = 2;
310 // Default behaviour: (long)13,
311 // (unsigned long long)19
312 // Use extensions 'u', 'l' and 'll' for integral
313 // literals (as in template arguments): 13l, 19ull
315 static unsigned int const style_literal_int = 4;
316 // Default behaviour: 4
317 // Use also an explicit
318 // cast for int in literals: (int)4
320 static unsigned int const style_compact_expr_ops = 8;
321 // Default behaviour: (i) < (3), sizeof (int)
322 // Don't output spaces around
323 // operators in expressions: (i)<(3), sizeof(int)
325 static unsigned int const style_sizeof_typename = 16;
326 // Default behaviour: sizeof (X::t)
327 // Put 'typename' infront of <nested-name>
328 // types inside a 'sizeof': sizeof (typename X::t)
330 public:
331 implementation_details(unsigned int style_flags = 0) :
332 M_style(style_flags) { }
333 virtual ~implementation_details() { }
334 bool get_style_void(void) const
335 { return (M_style & style_void); }
336 bool get_style_literal(void) const
337 { return (M_style & style_literal); }
338 bool get_style_literal_int(void) const
339 { return (M_style & style_literal_int); }
340 bool get_style_compact_expr_ops(void) const
341 { return (M_style & style_compact_expr_ops); }
342 bool get_style_sizeof_typename(void) const
343 { return (M_style & style_sizeof_typename); }
344 // This can be overridden by user implementations.
345 virtual bool decode_real(char* /* output */, unsigned long* /* input */,
346 size_t /* size_of_real */) const
347 { return false; }
350 template<typename Allocator>
351 class session
353 friend class qualifier_list<Allocator>;
354 typedef typename Allocator::template rebind<char>::other
355 char_Allocator;
356 typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
357 string_type;
359 private:
360 char const* M_str;
361 int M_pos;
362 int M_maxpos;
363 bool M_result;
364 int M_inside_template_args;
365 int M_inside_type;
366 int M_inside_substitution;
367 bool M_saw_destructor;
368 bool M_name_is_cdtor;
369 bool M_name_is_template;
370 bool M_name_is_conversion_operator;
371 bool M_template_args_need_space;
372 string_type M_function_name;
373 typedef typename Allocator::template rebind<int>::other
374 int_Allocator;
375 typedef typename Allocator::template rebind<substitution_st>::other
376 subst_Allocator;
377 std::vector<int, int_Allocator> M_template_arg_pos;
378 int M_template_arg_pos_offset;
379 std::vector<substitution_st, subst_Allocator> M_substitutions_pos;
380 implementation_details const& M_implementation_details;
381 #if _GLIBCXX_DEMANGLER_CWDEBUG
382 bool M_inside_add_substitution;
383 #endif
385 public:
386 explicit session(char const* in, int len,
387 implementation_details const& id = implementation_details())
388 : M_str(in), M_pos(0), M_maxpos(len - 1), M_result(true),
389 M_inside_template_args(0), M_inside_type(0),
390 M_inside_substitution(0), M_saw_destructor(false),
391 M_name_is_cdtor(false), M_name_is_template(false),
392 M_name_is_conversion_operator(false),
393 M_template_args_need_space(false), M_template_arg_pos_offset(0),
394 M_implementation_details(id)
395 #if _GLIBCXX_DEMANGLER_CWDEBUG
396 , M_inside_add_substitution(false)
397 #endif
400 static int
401 decode_encoding(string_type& output, char const* input, int len,
402 implementation_details const& id = implementation_details());
404 bool
405 decode_type(string_type& output,
406 qualifier_list<Allocator>* qualifiers = NULL)
408 string_type postfix;
409 bool res = decode_type_with_postfix(output, postfix, qualifiers);
410 output += postfix;
411 return res;
414 bool
415 remaining_input_characters(void) const
416 { return current() != 0; }
418 private:
419 char
420 current(void) const
421 { return (M_pos > M_maxpos) ? 0 : M_str[M_pos]; }
423 char
424 next_peek(void) const
425 { return (M_pos >= M_maxpos) ? 0 : M_str[M_pos + 1]; }
427 char
428 next(void)
429 { return (M_pos >= M_maxpos) ? 0 : M_str[++M_pos]; }
431 char
432 eat_current(void)
433 { return (M_pos > M_maxpos) ? 0 : M_str[M_pos++]; }
435 void
436 store(int& saved_pos)
437 { saved_pos = M_pos; }
439 void
440 restore(int saved_pos)
441 { M_pos = saved_pos; M_result = true; }
443 void
444 add_substitution(int start_pos,
445 substitution_nt sub_type,
446 int number_of_prefixes);
448 bool decode_type_with_postfix(string_type& prefix,
449 string_type& postfix, qualifier_list<Allocator>* qualifiers = NULL);
450 bool decode_bare_function_type(string_type& output);
451 bool decode_builtin_type(string_type& output);
452 bool decode_call_offset(string_type& output);
453 bool decode_class_enum_type(string_type& output);
454 bool decode_expression(string_type& output);
455 bool decode_literal(string_type& output);
456 bool decode_local_name(string_type& output);
457 bool decode_name(string_type& output,
458 string_type& nested_name_qualifiers);
459 bool decode_nested_name(string_type& output,
460 string_type& qualifiers);
461 bool decode_number(string_type& output);
462 bool decode_operator_name(string_type& output);
463 bool decode_source_name(string_type& output);
464 bool decode_substitution(string_type& output,
465 qualifier_list<Allocator>* qualifiers = NULL);
466 bool decode_template_args(string_type& output);
467 bool decode_template_param(string_type& output,
468 qualifier_list<Allocator>* qualifiers = NULL);
469 bool decode_unqualified_name(string_type& output);
470 bool decode_unscoped_name(string_type& output);
471 bool decode_non_negative_decimal_integer(string_type& output);
472 bool decode_special_name(string_type& output);
473 bool decode_real(string_type& output, size_t size_of_real);
476 template<typename Allocator>
477 #if !_GLIBCXX_DEMANGLER_CWDEBUG
478 inline
479 #endif
480 void
481 session<Allocator>::add_substitution(int start_pos,
482 substitution_nt sub_type,
483 int number_of_prefixes = 0)
485 if (!M_inside_substitution)
487 #if _GLIBCXX_DEMANGLER_CWDEBUG
488 if (M_inside_add_substitution)
489 return;
490 #endif
491 M_substitutions_pos.
492 push_back(substitution_st(start_pos,
493 sub_type, number_of_prefixes));
494 #if _GLIBCXX_DEMANGLER_CWDEBUG
495 if (!DEBUGCHANNELS::dc::demangler.is_on())
496 return;
497 string_type substitution_name("S");
498 int n = M_substitutions_pos.size() - 1;
499 if (n > 0)
500 substitution_name += (n <= 10) ? (char)(n + '0' - 1)
501 : (char)(n + 'A' - 11);
502 substitution_name += '_';
503 string_type subst;
504 int saved_pos = M_pos;
505 M_pos = start_pos;
506 M_inside_add_substitution = true;
507 _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.off() );
508 switch(sub_type)
510 case type:
511 decode_type(subst);
512 break;
513 case template_template_param:
514 decode_template_param(subst);
515 break;
516 case nested_name_prefix:
517 case nested_name_template_prefix:
518 for (int cnt = number_of_prefixes; cnt > 0; --cnt)
520 if (current() == 'I')
522 subst += ' ';
523 decode_template_args(subst);
525 else
527 if (cnt < number_of_prefixes)
528 subst += "::";
529 if (current() == 'S')
530 decode_substitution(subst);
531 else if (current() == 'T')
532 decode_template_param(subst);
533 else
534 decode_unqualified_name(subst);
537 break;
538 case unscoped_template_name:
539 decode_unscoped_name(subst);
540 break;
542 M_pos = saved_pos;
543 _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.on() );
544 _GLIBCXX_DEMANGLER_DOUT(dc::demangler,
545 "Adding substitution " << substitution_name
546 << " : " << subst
547 << " (from " << location_ct((char*)__builtin_return_address(0)
548 + builtin_return_address_offset)
549 << " <- " << location_ct((char*)__builtin_return_address(1)
550 + builtin_return_address_offset)
551 << " <- " << location_ct((char*)__builtin_return_address(2)
552 + builtin_return_address_offset)
553 << ").");
554 M_inside_add_substitution = false;
555 #endif
559 // We don't want to depend on locale (or include <cctype> for that matter).
560 // We also don't want to use "safe-ctype.h" because that headerfile is not
561 // available to the users.
562 inline bool isdigit(char c) { return c >= '0' && c <= '9'; }
563 inline bool islower(char c) { return c >= 'a' && c <= 'z'; }
564 inline bool isupper(char c) { return c >= 'A' && c <= 'Z'; }
565 inline char tolower(char c) { return isupper(c) ? c - 'A' + 'a' : c; }
568 // <non-negative decimal integer> ::= 0
569 // ::= 1|2|3|4|5|6|7|8|9 [<digit>+]
570 // <digit> ::= 0|1|2|3|4|5|6|7|8|9
572 template<typename Allocator>
573 bool
574 session<Allocator>::
575 decode_non_negative_decimal_integer(string_type& output)
577 char c = current();
578 if (c == '0')
580 output += '0';
581 eat_current();
583 else if (!isdigit(c))
584 M_result = false;
585 else
589 output += c;
591 while (isdigit((c = next())));
593 return M_result;
596 // <number> ::= [n] <non-negative decimal integer>
598 template<typename Allocator>
599 bool
600 session<Allocator>::decode_number(string_type& output)
602 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_number");
603 if (current() != 'n')
604 decode_non_negative_decimal_integer(output);
605 else
607 output += '-';
608 eat_current();
609 decode_non_negative_decimal_integer(output);
611 _GLIBCXX_DEMANGLER_RETURN;
614 // <builtin-type> ::= v # void
615 // ::= w # wchar_t
616 // ::= b # bool
617 // ::= c # char
618 // ::= a # signed char
619 // ::= h # unsigned char
620 // ::= s # short
621 // ::= t # unsigned short
622 // ::= i # int
623 // ::= j # unsigned int
624 // ::= l # long
625 // ::= m # unsigned long
626 // ::= x # long long, __int64
627 // ::= y # unsigned long long, __int64
628 // ::= n # __int128
629 // ::= o # unsigned __int128
630 // ::= f # float
631 // ::= d # double
632 // ::= e # long double, __float80
633 // ::= g # __float128
634 // ::= z # ellipsis
635 // ::= u <source-name> # vendor extended type
637 char const* const builtin_type_c[26] =
639 "signed char", // a
640 "bool", // b
641 "char", // c
642 "double", // d
643 "long double", // e
644 "float", // f
645 "__float128", // g
646 "unsigned char", // h
647 "int", // i
648 "unsigned int", // j
649 NULL, // k
650 "long", // l
651 "unsigned long", // m
652 "__int128", // n
653 "unsigned __int128", // o
654 NULL, // p
655 NULL, // q
656 NULL, // r
657 "short", // s
658 "unsigned short", // t
659 NULL, // u
660 "void", // v
661 "wchar_t", // w
662 "long long", // x
663 "unsigned long long", // y
664 "..." // z
668 template<typename Allocator>
669 bool
670 session<Allocator>::decode_builtin_type(string_type& output)
672 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_builtin_type");
673 char const* bt;
674 if (!islower(current()) || !(bt = builtin_type_c[current() - 'a']))
675 _GLIBCXX_DEMANGLER_FAILURE;
676 output += bt;
677 eat_current();
678 _GLIBCXX_DEMANGLER_RETURN;
681 // <class-enum-type> ::= <name>
683 template<typename Allocator>
684 bool
685 session<Allocator>::decode_class_enum_type(string_type& output)
687 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_class_enum_type");
688 string_type nested_name_qualifiers;
689 if (!decode_name(output, nested_name_qualifiers))
690 _GLIBCXX_DEMANGLER_FAILURE;
691 output += nested_name_qualifiers;
692 _GLIBCXX_DEMANGLER_RETURN;
695 // <substitution> ::=
696 // S <seq-id> _
697 // S_
698 // St # ::std::
699 // Sa # ::std::allocator
700 // Sb # ::std::basic_string
701 // Ss # ::std::basic_string<char, std::char_traits<char>,
702 // std::allocator<char> >
703 // Si # ::std::basic_istream<char, std::char_traits<char> >
704 // So # ::std::basic_ostream<char, std::char_traits<char> >
705 // Sd # ::std::basic_iostream<char, std::char_traits<char> >
707 // <seq-id> ::=
708 // 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
709 // [<seq-id>] # Base 36 number
711 template<typename Allocator>
712 bool
713 session<Allocator>::decode_substitution(string_type& output,
714 qualifier_list<Allocator>* qualifiers)
716 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_substitution");
717 unsigned int value = 0;
718 char c = next();
719 if (c != '_')
721 switch(c)
723 case 'a':
725 output += "std::allocator";
726 if (!M_inside_template_args)
728 M_function_name = "allocator";
729 M_name_is_template = true;
730 M_name_is_cdtor = false;
731 M_name_is_conversion_operator = false;
733 eat_current();
734 if (qualifiers)
735 qualifiers->printing_suppressed();
736 _GLIBCXX_DEMANGLER_RETURN;
738 case 'b':
740 output += "std::basic_string";
741 if (!M_inside_template_args)
743 M_function_name = "basic_string";
744 M_name_is_template = true;
745 M_name_is_cdtor = false;
746 M_name_is_conversion_operator = false;
748 eat_current();
749 if (qualifiers)
750 qualifiers->printing_suppressed();
751 _GLIBCXX_DEMANGLER_RETURN;
753 case 'd':
754 output += "std::iostream";
755 if (!M_inside_template_args)
757 M_function_name = "iostream";
758 M_name_is_template = true;
759 M_name_is_cdtor = false;
760 M_name_is_conversion_operator = false;
762 eat_current();
763 if (qualifiers)
764 qualifiers->printing_suppressed();
765 _GLIBCXX_DEMANGLER_RETURN;
766 case 'i':
767 output += "std::istream";
768 if (!M_inside_template_args)
770 M_function_name = "istream";
771 M_name_is_template = true;
772 M_name_is_cdtor = false;
773 M_name_is_conversion_operator = false;
775 eat_current();
776 if (qualifiers)
777 qualifiers->printing_suppressed();
778 _GLIBCXX_DEMANGLER_RETURN;
779 case 'o':
780 output += "std::ostream";
781 if (!M_inside_template_args)
783 M_function_name = "ostream";
784 M_name_is_template = true;
785 M_name_is_cdtor = false;
786 M_name_is_conversion_operator = false;
788 eat_current();
789 if (qualifiers)
790 qualifiers->printing_suppressed();
791 _GLIBCXX_DEMANGLER_RETURN;
792 case 's':
793 output += "std::string";
794 if (!M_inside_template_args)
796 M_function_name = "string";
797 M_name_is_template = true;
798 M_name_is_cdtor = false;
799 M_name_is_conversion_operator = false;
801 eat_current();
802 if (qualifiers)
803 qualifiers->printing_suppressed();
804 _GLIBCXX_DEMANGLER_RETURN;
805 case 't':
806 output += "std";
807 eat_current();
808 if (qualifiers)
809 qualifiers->printing_suppressed();
810 _GLIBCXX_DEMANGLER_RETURN;
811 default:
812 for(;; c = next())
814 if (isdigit(c))
815 value = value * 36 + c - '0';
816 else if (isupper(c))
817 value = value * 36 + c - 'A' + 10;
818 else if (c == '_')
819 break;
820 else
821 _GLIBCXX_DEMANGLER_FAILURE;
823 ++value;
824 break;
827 eat_current();
828 if (value >= M_substitutions_pos.size() ||
829 M_inside_type > 20) // Rather than core dump.
830 _GLIBCXX_DEMANGLER_FAILURE;
831 ++M_inside_substitution;
832 int saved_pos = M_pos;
833 substitution_st& substitution(M_substitutions_pos[value]);
834 M_pos = substitution.M_start_pos;
835 switch(substitution.M_type)
837 case type:
838 decode_type(output, qualifiers);
839 break;
840 case template_template_param:
841 decode_template_param(output, qualifiers);
842 break;
843 case nested_name_prefix:
844 case nested_name_template_prefix:
845 for (int cnt = substitution.M_number_of_prefixes; cnt > 0; --cnt)
847 if (current() == 'I')
849 if (M_template_args_need_space)
850 output += ' ';
851 M_template_args_need_space = false;
852 if (!decode_template_args(output))
853 _GLIBCXX_DEMANGLER_FAILURE;
855 else
857 if (cnt < substitution.M_number_of_prefixes)
858 output += "::";
859 if (current() == 'S')
861 if (!decode_substitution(output))
862 _GLIBCXX_DEMANGLER_FAILURE;
864 else if (!decode_unqualified_name(output))
865 _GLIBCXX_DEMANGLER_FAILURE;
868 if (qualifiers)
869 qualifiers->printing_suppressed();
870 break;
871 case unscoped_template_name:
872 decode_unscoped_name(output);
873 if (qualifiers)
874 qualifiers->printing_suppressed();
875 break;
877 M_pos = saved_pos;
878 --M_inside_substitution;
879 _GLIBCXX_DEMANGLER_RETURN;
882 // <template-param> ::= T_ # first template parameter
883 // ::= T <parameter-2 non-negative number> _
885 template<typename Allocator>
886 bool
887 session<Allocator>::decode_template_param(string_type& output,
888 qualifier_list<Allocator>* qualifiers)
890 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_parameter");
891 if (current() != 'T')
892 _GLIBCXX_DEMANGLER_FAILURE;
893 unsigned int value = 0;
894 char c;
895 if ((c = next()) != '_')
897 while(isdigit(c))
899 value = value * 10 + c - '0';
900 c = next();
902 ++value;
904 if (eat_current() != '_')
905 _GLIBCXX_DEMANGLER_FAILURE;
906 value += M_template_arg_pos_offset;
907 if (value >= M_template_arg_pos.size())
908 _GLIBCXX_DEMANGLER_FAILURE;
909 int saved_pos = M_pos;
910 M_pos = M_template_arg_pos[value];
911 if (M_inside_type > 20) // Rather than core dump.
912 _GLIBCXX_DEMANGLER_FAILURE;
913 ++M_inside_substitution;
914 if (current() == 'X')
916 eat_current();
917 decode_expression(output);
919 else if (current() == 'L')
920 decode_literal(output);
921 else
922 decode_type(output, qualifiers);
923 --M_inside_substitution;
924 M_pos = saved_pos;
925 _GLIBCXX_DEMANGLER_RETURN;
928 template<typename Allocator>
929 bool
930 session<Allocator>::decode_real(string_type& output, size_t size_of_real)
932 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_real");
934 unsigned long words[4]; // 32 bit per long, maximum of 128 bits.
935 unsigned long* word = &words[0];
937 int saved_pos;
938 store(saved_pos);
940 // The following assumes that leading zeroes are also included in the
941 // mangled name, I am not sure that is conforming to the C++-ABI, but
942 // it is what g++ does.
943 unsigned char nibble, c = current();
944 for(size_t word_cnt = size_of_real / 4; word_cnt > 0; --word_cnt)
946 for (int nibble_cnt = 0; nibble_cnt < 8; ++nibble_cnt)
948 // Translate character into nibble.
949 if (c < '0' || c > 'f')
950 _GLIBCXX_DEMANGLER_FAILURE;
951 if (c <= '9')
952 nibble = c - '0';
953 else if (c >= 'a')
954 nibble = c - 'a' + 10;
955 else
956 _GLIBCXX_DEMANGLER_FAILURE;
957 // Write nibble into word array.
958 if (nibble_cnt == 0)
959 *word = nibble << 28;
960 else
961 *word |= (nibble << (28 - 4 * nibble_cnt));
962 c = next();
964 ++word;
966 char buf[24];
967 if (M_implementation_details.decode_real(buf, words, size_of_real))
969 output += buf;
970 _GLIBCXX_DEMANGLER_RETURN;
972 restore(saved_pos);
974 output += '[';
975 c = current();
976 for(size_t nibble_cnt = 0; nibble_cnt < 2 * size_of_real; ++nibble_cnt)
978 if (c < '0' || c > 'f' || (c > '9' && c < 'a'))
979 _GLIBCXX_DEMANGLER_FAILURE;
980 output += c;
981 c = next();
983 output += ']';
985 _GLIBCXX_DEMANGLER_RETURN;
988 template<typename Allocator>
989 bool
990 session<Allocator>::decode_literal(string_type& output)
992 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_literal");
993 eat_current(); // Eat the 'L'.
994 if (current() == '_')
996 if (next() != 'Z')
997 _GLIBCXX_DEMANGLER_FAILURE;
998 eat_current();
999 if ((M_pos += decode_encoding(output, M_str + M_pos,
1000 M_maxpos - M_pos + 1, M_implementation_details)) < 0)
1001 _GLIBCXX_DEMANGLER_FAILURE;
1003 else
1005 // Special cases
1006 if (current() == 'b')
1008 if (next() == '0')
1009 output += "false";
1010 else
1011 output += "true";
1012 eat_current();
1013 _GLIBCXX_DEMANGLER_RETURN;
1015 char c = current();
1016 if ((c == 'i' || c == 'j' || c == 'l' ||
1017 c == 'm' || c == 'x' || c == 'y') &&
1018 M_implementation_details.get_style_literal())
1019 eat_current();
1020 else if (c == 'i' &&
1021 !M_implementation_details.get_style_literal_int())
1022 eat_current();
1023 else
1025 output += '(';
1026 if (!decode_type(output))
1027 _GLIBCXX_DEMANGLER_FAILURE;
1028 output += ')';
1030 if (c >= 'd' && c <= 'g')
1032 size_t size_of_real = (c == 'd') ? sizeof(double) :
1033 ((c == 'f') ? sizeof(float) :
1034 (c == 'e') ? sizeof(long double) : 16);
1035 if (!decode_real(output, size_of_real))
1036 _GLIBCXX_DEMANGLER_FAILURE;
1038 else if (!decode_number(output))
1039 _GLIBCXX_DEMANGLER_FAILURE;
1040 if (M_implementation_details.get_style_literal())
1042 if (c == 'j' || c == 'm' || c == 'y')
1043 output += 'u';
1044 if (c == 'l' || c == 'm')
1045 output += 'l';
1046 if (c == 'x' || c == 'y')
1047 output += "ll";
1050 _GLIBCXX_DEMANGLER_RETURN;
1053 // <operator-name> ::=
1054 // nw # new
1055 // na # new[]
1056 // dl # delete
1057 // da # delete[]
1058 // ps # + (unary)
1059 // ng # - (unary)
1060 // ad # & (unary)
1061 // de # * (unary)
1062 // co # ~
1063 // pl # +
1064 // mi # -
1065 // ml # *
1066 // dv # /
1067 // rm # %
1068 // an # &
1069 // or # |
1070 // eo # ^
1071 // aS # =
1072 // pL # +=
1073 // mI # -=
1074 // mL # *=
1075 // dV # /=
1076 // rM # %=
1077 // aN # &=
1078 // oR # |=
1079 // eO # ^=
1080 // ls # <<
1081 // rs # >>
1082 // lS # <<=
1083 // rS # >>=
1084 // eq # ==
1085 // ne # !=
1086 // lt # <
1087 // gt # >
1088 // le # <=
1089 // ge # >=
1090 // nt # !
1091 // aa # &&
1092 // oo # ||
1093 // pp # ++
1094 // mm # --
1095 // cm # ,
1096 // pm # ->*
1097 // pt # ->
1098 // cl # ()
1099 // ix # []
1100 // qu # ?
1101 // st # sizeof (a type)
1102 // sz # sizeof (an expression)
1103 // cv <type> # (cast)
1104 // v <digit> <source-name> # vendor extended operator
1106 // Symbol operator codes exist of two characters, we need to find a
1107 // quick hash so that their names can be looked up in a table.
1109 // The puzzle :)
1110 // Shift the rows so that there is at most one character per column.
1112 // A perfect solution (Oh no, it's THE MATRIX!):
1113 // horizontal
1114 // ....................................... offset + 'a'
1115 // a, a||d|||||||||n||||s|||||||||||||||||||| 0
1116 // c, || |||||||lm o||| |||||||||||||||||||| 0
1117 // d, || a|||e|| l|| ||||||v||||||||||||| 4
1118 // e, || ||| || || |||o|q ||||||||||||| 8
1119 // g, || ||| || || e|| | ||||||||t|||| 15
1120 // i, || ||| || || || | |||||||| |||x 15
1121 // l, |e ||| || st || | |||||||| ||| -2
1122 // m, | |i| lm || | |||||||| ||| -2
1123 // n, a e g t| w |||||||| ||| 1
1124 // o, | ||||o||r ||| 16
1125 // p, | ||lm |p st| 17
1126 // q, | u| | | 6
1127 // r, m s | | 9
1128 // s, t z 12
1129 // .......................................
1130 // ^ ^__ second character
1131 // |___ first character
1134 // Putting that solution in tables:
1136 char const offset_table_c [1 + CHAR_MAX - CHAR_MIN ] =
1138 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1139 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1140 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1143 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1144 #if (CHAR_MIN < 0)
1145 // Add -CHAR_MIN extra zeroes (128):
1146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1148 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1152 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1153 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1154 // a b c d e f g h i j k
1155 0, -97, 0, -97, -93, -89, 0, -82, 0, -82, 0, 0,
1156 // l m n o p q r s t u v
1157 -99, -99, -96, -81, -80, -91, -88, -85, 0, 0, 0,
1158 #else
1159 // a b c d e f g h i j k
1160 0, 159, 0, 159, 163, 167, 0, 174, 0, 174, 0, 0,
1161 // l m n o p q r s t u v
1162 157, 157, 160, 175, 176, 165, 168, 171, 0, 0, 0,
1163 #endif
1164 // ... more zeros
1167 enum xary_nt {
1168 unary,
1169 binary,
1170 trinary
1173 struct entry_st
1175 char const* opcode;
1176 char const* symbol_name;
1177 xary_nt type;
1180 entry_st const symbol_name_table_c[39] = {
1181 { "aa", "operator&&", binary },
1182 { "na", "operator new[]", unary },
1183 { "le", "operator<=", binary },
1184 { "ad", "operator&", unary },
1185 { "da", "operator delete[]", unary },
1186 { "ne", "operator!=", binary },
1187 { "mi=", "operator-", binary },
1188 { "ng", "operator-", unary },
1189 { "de", "operator*", unary },
1190 { "ml=", "operator*", binary },
1191 { "mm", "operator--", unary },
1192 { "cl", "operator()", unary },
1193 { "cm", "operator,", binary },
1194 { "an=", "operator&", binary },
1195 { "co", "operator~", binary },
1196 { "dl", "operator delete", unary },
1197 { "ls=", "operator<<", binary },
1198 { "lt", "operator<", binary },
1199 { "as=", "operator", binary },
1200 { "ge", "operator>=", binary },
1201 { "nt", "operator!", unary },
1202 { "rm=", "operator%", binary },
1203 { "eo=", "operator^", binary },
1204 { "nw", "operator new", unary },
1205 { "eq", "operator==", binary },
1206 { "dv=", "operator/", binary },
1207 { "qu", "operator?", trinary },
1208 { "rs=", "operator>>", binary },
1209 { "pl=", "operator+", binary },
1210 { "pm", "operator->*", binary },
1211 { "oo", "operator||", binary },
1212 { "st", "sizeof", unary },
1213 { "pp", "operator++", unary },
1214 { "or=", "operator|", binary },
1215 { "gt", "operator>", binary },
1216 { "ps", "operator+", unary },
1217 { "pt", "operator->", binary },
1218 { "sz", "sizeof", unary },
1219 { "ix", "operator[]", unary }
1222 template<typename Allocator>
1223 bool
1224 session<Allocator>::decode_operator_name(string_type& output)
1226 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_operator_name");
1228 char opcode0 = current();
1229 char opcode1 = tolower(next());
1231 register char hash;
1232 if ((hash = offset_table_c[opcode0 - CHAR_MIN]))
1234 hash += opcode1;
1235 if (
1236 #if (CHAR_MIN < 0)
1237 hash >= 0 &&
1238 #endif
1239 hash < 39)
1241 int index = static_cast<int>(static_cast<unsigned char>(hash));
1242 entry_st entry = symbol_name_table_c[index];
1243 if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1244 && (opcode1 == current() || entry.opcode[2] == '='))
1246 output += entry.symbol_name;
1247 if (opcode1 != current())
1248 output += '=';
1249 eat_current();
1250 if (hash == 16 || hash == 17)
1251 M_template_args_need_space = true;
1252 _GLIBCXX_DEMANGLER_RETURN;
1254 else if (opcode0 == 'c' && opcode1 == 'v') // casting operator
1256 eat_current();
1257 output += "operator ";
1258 if (current() == 'T')
1260 // This is a templated cast operator.
1261 // It must be of the form "cvT_I...E".
1262 // Let M_template_arg_pos already point
1263 // to the template argument.
1264 M_template_arg_pos_offset = M_template_arg_pos.size();
1265 M_template_arg_pos.push_back(M_pos + 3);
1267 if (!decode_type(output))
1268 _GLIBCXX_DEMANGLER_FAILURE;
1269 if (!M_inside_template_args)
1270 M_name_is_conversion_operator = true;
1271 _GLIBCXX_DEMANGLER_RETURN;
1275 _GLIBCXX_DEMANGLER_FAILURE;
1279 // <expression> ::= <unary operator-name> <expression>
1280 // ::= <binary operator-name> <expression> <expression>
1281 // ::= <trinary operator-name> <expression> <expression> <expression>
1282 // ::= st <type>
1283 // ::= <template-param>
1284 // ::= sr <type> <unqualified-name> # dependent name
1285 // ::= sr <type> <unqualified-name> <template-args> # dependent template-id
1286 // ::= <expr-primary>
1288 // <expr-primary> ::= L <type> <value number> E # integer literal
1289 // ::= L <type> <value float> E # floating literal
1290 // ::= L <mangled-name> E # external name
1292 template<typename Allocator>
1293 bool
1294 session<Allocator>::decode_expression(string_type& output)
1296 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_expression");
1297 if (current() == 'T')
1299 if (!decode_template_param(output))
1300 _GLIBCXX_DEMANGLER_FAILURE;
1301 _GLIBCXX_DEMANGLER_RETURN;
1303 else if (current() == 'L')
1305 if (!decode_literal(output))
1306 _GLIBCXX_DEMANGLER_FAILURE;
1307 if (current() != 'E')
1308 _GLIBCXX_DEMANGLER_FAILURE;
1309 eat_current();
1310 _GLIBCXX_DEMANGLER_RETURN;
1312 else if (current() == 's')
1314 char opcode1 = next();
1315 if (opcode1 == 't' || opcode1 == 'z')
1317 eat_current();
1318 if (M_implementation_details.get_style_compact_expr_ops())
1319 output += "sizeof(";
1320 else
1321 output += "sizeof (";
1322 if (opcode1 == 't')
1324 // I cannot think of a mangled name that is valid for both cases
1325 // when just replacing the 't' by a 'z' or vica versa, which
1326 // indicates that there is no ambiguity that dictates the need
1327 // for a seperate "st" case, except to be able catch invalid
1328 // mangled names. However there CAN be ambiguity in the demangled
1329 // name when there are both a type and a symbol of the same name,
1330 // which then leads to different encoding (of course) with
1331 // sizeof (type) or sizeof (expression) respectively, but that
1332 // ambiguity is not per se related to "sizeof" except that that
1333 // is the only place where both a type AND an expression are valid
1334 // in as part of a (template function) type.
1336 // Example:
1338 // struct B { typedef int t; };
1339 // struct A : public B { static int t[2]; };
1340 // template<int i, int j> struct C { typedef int q; };
1341 // template<int i, typename T>
1342 // void f(typename C<sizeof (typename T::t),
1343 // sizeof (T::t)>::q) { }
1344 // void instantiate() { f<5, A>(0); }
1346 // Leads to _Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE which
1347 // demangles as
1348 // void f<5, A>(C<sizeof (T::t), sizeof (T::t)>::q)
1350 // This is ambiguity is very unlikely to happen and it is kind
1351 // of fuzzy to detect when adding a 'typename' makes sense.
1353 if (M_implementation_details.get_style_sizeof_typename())
1355 // We can only get here inside a template parameter,
1356 // so this is syntactically correct if the given type is
1357 // a typedef. The only disadvantage is that it is inconsistent
1358 // with all other places where the 'typename' keyword should be
1359 // used and we don't.
1360 // With this, the above example will demangle as
1361 // void f<5, A>(C<sizeof (typename T::t), sizeof (T::t)>::q)
1362 if (current() == 'N' || // <nested-name>
1363 // This should be a safe bet.
1364 (current() == 'S' &&
1365 next_peek() == 't')) // std::something, guess that
1366 // this involves a typedef.
1367 output += "typename ";
1369 if (!decode_type(output))
1370 _GLIBCXX_DEMANGLER_FAILURE;
1372 else
1374 if (!decode_expression(output))
1375 _GLIBCXX_DEMANGLER_FAILURE;
1377 output += ')';
1378 _GLIBCXX_DEMANGLER_RETURN;
1380 else if (current() == 'r')
1382 eat_current();
1383 if (!decode_type(output))
1384 _GLIBCXX_DEMANGLER_FAILURE;
1385 output += "::";
1386 if (!decode_unqualified_name(output))
1387 _GLIBCXX_DEMANGLER_FAILURE;
1388 if (current() != 'I' || decode_template_args(output))
1389 _GLIBCXX_DEMANGLER_RETURN;
1392 else
1394 char opcode0 = current();
1395 char opcode1 = tolower(next());
1397 register char hash;
1398 if ((hash = offset_table_c[opcode0 - CHAR_MIN]))
1400 hash += opcode1;
1401 if (
1402 #if (CHAR_MIN < 0)
1403 hash >= 0 &&
1404 #endif
1405 hash < 39)
1407 int index = static_cast<int>(static_cast<unsigned char>(hash));
1408 entry_st entry = symbol_name_table_c[index];
1409 if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1410 && (opcode1 == current() || entry.opcode[2] == '='))
1412 char const* op = entry.symbol_name + 8; // Skip "operator".
1413 if (*op == ' ') // operator new and delete.
1414 ++op;
1415 if (entry.type == unary)
1416 output += op;
1417 bool is_eq = (opcode1 != current());
1418 eat_current();
1419 if (index == 34 && M_inside_template_args) // operator>
1420 output += '(';
1421 output += '(';
1422 if (!decode_expression(output))
1423 _GLIBCXX_DEMANGLER_FAILURE;
1424 output += ')';
1425 if (entry.type != unary)
1427 if (!M_implementation_details.get_style_compact_expr_ops())
1428 output += ' ';
1429 output += op;
1430 if (is_eq)
1431 output += '=';
1432 if (!M_implementation_details.get_style_compact_expr_ops())
1433 output += ' ';
1434 output += '(';
1435 if (!decode_expression(output))
1436 _GLIBCXX_DEMANGLER_FAILURE;
1437 output += ')';
1438 if (index == 34 && M_inside_template_args)
1439 output += ')';
1440 if (entry.type == trinary)
1442 if (M_implementation_details.get_style_compact_expr_ops())
1443 output += ":(";
1444 else
1445 output += " : (";
1446 if (!decode_expression(output))
1447 _GLIBCXX_DEMANGLER_FAILURE;
1448 output += ')';
1451 _GLIBCXX_DEMANGLER_RETURN;
1453 else if (opcode0 == 'c' &&
1454 opcode1 == 'v') // casting operator.
1456 eat_current();
1457 output += '(';
1458 if (!decode_type(output))
1459 _GLIBCXX_DEMANGLER_FAILURE;
1460 output += ")(";
1461 if (!decode_expression(output))
1462 _GLIBCXX_DEMANGLER_FAILURE;
1463 output += ')';
1464 _GLIBCXX_DEMANGLER_RETURN;
1469 _GLIBCXX_DEMANGLER_FAILURE;
1473 // <template-args> ::= I <template-arg>+ E
1474 // <template-arg> ::= <type> # type or template
1475 // ::= L <type> <value number> E # integer literal
1476 // ::= L <type> <value float> E # floating literal
1477 // ::= L <mangled-name> E # external name
1478 // ::= X <expression> E # expression
1479 template<typename Allocator>
1480 bool
1481 session<Allocator>::decode_template_args(string_type& output)
1483 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_args");
1484 if (eat_current() != 'I')
1485 _GLIBCXX_DEMANGLER_FAILURE;
1486 int prev_size = M_template_arg_pos.size();
1487 ++M_inside_template_args;
1488 if (M_template_args_need_space)
1490 output += ' ';
1491 M_template_args_need_space = false;
1493 output += '<';
1494 for(;;)
1496 if (M_inside_template_args == 1 && !M_inside_type)
1497 M_template_arg_pos.push_back(M_pos);
1498 if (current() == 'X')
1500 eat_current();
1501 if (!decode_expression(output))
1502 _GLIBCXX_DEMANGLER_FAILURE;
1503 if (current() != 'E')
1504 _GLIBCXX_DEMANGLER_FAILURE;
1505 eat_current();
1507 else if (current() == 'L')
1509 if (!decode_literal(output))
1510 _GLIBCXX_DEMANGLER_FAILURE;
1511 if (current() != 'E')
1512 _GLIBCXX_DEMANGLER_FAILURE;
1513 eat_current();
1515 else if (!decode_type(output))
1516 _GLIBCXX_DEMANGLER_FAILURE;
1517 if (current() == 'E')
1518 break;
1519 output += ", ";
1521 eat_current();
1522 if (*(output.rbegin()) == '>')
1523 output += ' ';
1524 output += '>';
1525 --M_inside_template_args;
1526 if (!M_inside_template_args && !M_inside_type)
1528 M_name_is_template = true;
1529 M_template_arg_pos_offset = prev_size;
1531 _GLIBCXX_DEMANGLER_RETURN;
1534 // <bare-function-type> ::=
1535 // <signature type>+ # Types are parameter types.
1537 // Note that the possible return type of the <bare-function-type>
1538 // has already been eaten before we call this function. This makes
1539 // our <bare-function-type> slightly different from the one in
1540 // the C++-ABI description.
1542 template<typename Allocator>
1543 bool
1544 session<Allocator>::decode_bare_function_type(string_type& output)
1546 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_bare_function_type");
1547 if (M_saw_destructor)
1549 if (eat_current() != 'v' || (current() != 'E' && current() != 0))
1550 _GLIBCXX_DEMANGLER_FAILURE;
1551 output += "()";
1552 M_saw_destructor = false;
1553 _GLIBCXX_DEMANGLER_RETURN;
1555 if (current() == 'v' && !M_implementation_details.get_style_void())
1557 eat_current();
1558 if (current() != 'E' && current() != 0)
1559 _GLIBCXX_DEMANGLER_FAILURE;
1560 output += "()";
1561 M_saw_destructor = false;
1562 _GLIBCXX_DEMANGLER_RETURN;
1564 output += '(';
1565 M_template_args_need_space = false;
1566 if (!decode_type(output)) // Must have at least one parameter.
1567 _GLIBCXX_DEMANGLER_FAILURE;
1568 while (current() != 'E' && current() != 0)
1570 output += ", ";
1571 if (!decode_type(output))
1572 _GLIBCXX_DEMANGLER_FAILURE;
1574 output += ')';
1575 _GLIBCXX_DEMANGLER_RETURN;
1578 // <type> ::=
1579 // <builtin-type> # Starts with a lower case character != r.
1580 // <function-type> # Starts with F
1581 // <class-enum-type> # Starts with N, S, C, D, Z, a digit or a lower
1582 // # case character. Since a lower case character
1583 // # would be an operator name, that would be an
1584 // # error. The S is a substitution or St
1585 // # (::std::). A 'C' would be a constructor and
1586 // # thus also an error.
1587 // <template-param> # Starts with T
1588 // <substitution> # Starts with S
1589 // <template-template-param> <template-args> # Starts with T or S,
1590 // # equivalent with the above.
1592 // <array-type> # Starts with A
1593 // <pointer-to-member-type> # Starts with M
1594 // <CV-qualifiers> <type> # Starts with r, V or K
1595 // P <type> # pointer-to # Starts with P
1596 // R <type> # reference-to # Starts with R
1597 // C <type> # complex (C 2000) # Starts with C
1598 // G <type> # imaginary (C 2000)# Starts with G
1599 // U <source-name> <type> # vendor extended type qualifier,
1600 // # starts with U
1602 // <template-template-param> ::= <template-param>
1603 // ::= <substitution>
1605 // My own analysis of how to decode qualifiers:
1607 // F is a <function-type>, <T> is a <builtin-type>, <class-enum-type>,
1608 // <template-param> or <template-template-param> <template-args>.
1609 // <Q> represents a series of qualifiers (not G or C).
1610 // <C> is an unqualified type.
1611 // <R> is a qualified type.
1612 // <B> is the bare-function-type without return type.
1613 // <I> is the array index.
1614 // Substitutions:
1615 // <Q>M<C><Q2>F<R><B>E ==> R (C::*Q)B Q2 "<C>", "F<R><B>E"
1616 // (<R> and <B> recursive),
1617 // "M<C><Q2>F<R><B>E".
1618 // <Q>F<R><B>E ==> R (Q)B "<R>", "<B>" (<B> recursive)
1619 // and "F<R><B>E".
1621 // Note that if <R> has postfix qualifiers (an array or function), then
1622 // those are added AFTER the (member) function type. For example:
1623 // <Q>FPA<R><B>E ==> R (*(Q)B) [], where the PA added the prefix
1624 // "(*" and the postfix ") []".
1626 // <Q>G<T> ==> imaginary T Q "<T>", "G<T>" (<T> recursive).
1627 // <Q>C<T> ==> complex T Q "<T>", "C<T>" (<T> recursive).
1628 // <Q><T> ==> T Q "<T>" (<T> recursive).
1630 // where <Q> is any of:
1632 // <Q>P ==> *Q "P..."
1633 // <Q>R ==> &Q "R..."
1634 // <Q>[K|V|r]+ ==> [ const| volatile| restrict]+Q "KVr..."
1635 // <Q>U<S> ==> SQ "U<S>..."
1636 // <Q>M<C> ==> C::*Q "M<C>..." (<C> recurs.)
1637 // A<I> ==> [I] "A<I>..." (<I> recurs.)
1638 // <Q>A<I> ==> (Q) [I] "A<I>..." (<I> recurs.)
1639 // Note that when <Q> ends on an A<I2> then the brackets are omitted
1640 // and no space is written between the two:
1641 // A<I2>A<I> ==> [I2][I]
1642 // If <Q> ends on [KVr]+, which can happen in combination with
1643 // substitutions only, then special handling is required, see below.
1645 // A <substitution> is handled with an input position switch during which
1646 // new substitutions are turned off. Because recursive handling of types
1647 // (and therefore the order in which substitutions must be generated) must
1648 // be done left to right, but the generation of Q needs processing right to
1649 // left, substitutions per <type> are generated by reading the input left
1650 // to right and marking the starts of all substitutions only - implicitly
1651 // finishing them at the end of the type. Then the output and real
1652 // substitutions are generated.
1654 // The following comment was for the demangling of g++ version 3.0.x. The
1655 // mangling (and I believe even the ABI description) have been fixed now
1656 // (as of g++ version 3.1).
1658 // g++ 3.0.x only:
1659 // The ABI specifies for pointer-to-member function types the format
1660 // <Q>M<T>F<R><B>E. In other words, the qualifier <Q2> (see above) is
1661 // implicitely contained in <T> instead of explicitly part of the M format.
1662 // I am convinced that this is a bug in the ABI. Unfortunately, this is
1663 // how we have to demangle things as it has a direct impact on the order
1664 // in which substitutions are stored. This ill-formed design results in
1665 // rather ill-formed demangler code too however :/
1667 // <Q2> is now explicitely part of the M format.
1668 // For some weird reason, g++ (3.2.1) does not add substitutions for
1669 // qualified member function pointers. I think that is another bug.
1672 // In the case of
1673 // <Q>A<I>
1674 // where <Q> ends on [K|V|r]+ then that part should be processed as
1675 // if it was behind the A<I> instead of in front of it. This is
1676 // because a constant array of ints is normally always mangled as
1677 // an array of constant ints. KVr qualifiers can end up in front
1678 // of an array when the array is part of a substitution or template
1679 // parameter, but the demangling should still result in the same
1680 // syntax; thus KA2_i (const array of ints) must result in the same
1681 // demangling as A2_Ki (array of const ints). As a result we must
1682 // demangle ...[...[[KVr]+A<I0>][KVr]+A<I1>]...[KVr]+A<In>[KVr]+
1683 // as A<I0>A<I1>...A<In>[KVr]+ where each K, V and r in the series
1684 // collapses to a single character at the right of the string.
1685 // For example:
1686 // VA9_KrA6_KVi --> A9_A6_KVri --> int volatile const restrict [9][6]
1687 // Note that substitutions are still added as usual (the translation
1688 // to A9_A6_KVri does not really happen).
1690 // This decoding is achieved by delaying the decoding of any sequence
1691 // of [KVrA]'s and processing them together in the order: first the
1692 // short-circuited KVr part and then the arrays.
1693 static int const cvq_K = 1; // Saw at least one K
1694 static int const cvq_V = 2; // Saw at least one V
1695 static int const cvq_r = 4; // Saw at least one r
1696 static int const cvq_A = 8; // Saw at least one A
1697 static int const cvq_last = 16; // No remaining qualifiers.
1698 static int const cvq_A_cnt = 32; // Bit 5 and higher represent the
1699 // number of A's in the series.
1700 // In the function below, iter_array points to the first (right most)
1701 // A in the series, if any.
1702 template<typename Allocator>
1703 void
1704 qualifier_list<Allocator>::decode_KVrA(
1705 string_type& prefix, string_type& postfix, int cvq,
1706 typename qual_vector::const_reverse_iterator const& iter_array) const
1708 _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA");
1709 if ((cvq & cvq_K))
1710 prefix += " const";
1711 if ((cvq & cvq_V))
1712 prefix += " volatile";
1713 if ((cvq & cvq_r))
1714 prefix += " restrict";
1715 if ((cvq & cvq_A))
1717 int n = cvq >> 5;
1718 for (typename qual_vector::
1719 const_reverse_iterator iter = iter_array;
1720 iter != M_qualifier_starts.rend(); ++iter)
1722 switch((*iter).first_qualifier())
1724 case 'K':
1725 case 'V':
1726 case 'r':
1727 break;
1728 case 'A':
1730 string_type index = (*iter).get_optional_type();
1731 if (--n == 0 && (cvq & cvq_last))
1732 postfix = " [" + index + "]" + postfix;
1733 else if (n > 0)
1734 postfix = "[" + index + "]" + postfix;
1735 else
1737 prefix += " (";
1738 postfix = ") [" + index + "]" + postfix;
1740 break;
1742 default:
1743 _GLIBCXX_DEMANGLER_RETURN3;
1747 _GLIBCXX_DEMANGLER_RETURN3;
1750 template<typename Allocator>
1751 void
1752 qualifier_list<Allocator>::decode_qualifiers(
1753 string_type& prefix,
1754 string_type& postfix,
1755 bool member_function_pointer_qualifiers = false) const
1757 _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers");
1758 int cvq = 0;
1759 typename qual_vector::const_reverse_iterator iter_array;
1760 for(typename qual_vector::
1761 const_reverse_iterator iter = M_qualifier_starts.rbegin();
1762 iter != M_qualifier_starts.rend(); ++iter)
1764 if (!member_function_pointer_qualifiers
1765 && !(*iter).part_of_substitution())
1767 int saved_inside_substitution = M_demangler.M_inside_substitution;
1768 M_demangler.M_inside_substitution = 0;
1769 M_demangler.add_substitution((*iter).get_start_pos(), type);
1770 M_demangler.M_inside_substitution = saved_inside_substitution;
1772 char qualifier_char = (*iter).first_qualifier();
1773 for(; qualifier_char; qualifier_char = (*iter).next_qualifier())
1775 switch(qualifier_char)
1777 case 'P':
1778 if (cvq)
1780 decode_KVrA(prefix, postfix, cvq, iter_array);
1781 cvq = 0;
1783 prefix += "*";
1784 break;
1785 case 'R':
1786 if (cvq)
1788 decode_KVrA(prefix, postfix, cvq, iter_array);
1789 cvq = 0;
1791 prefix += "&";
1792 break;
1793 case 'K':
1794 cvq |= cvq_K;
1795 continue;
1796 case 'V':
1797 cvq |= cvq_V;
1798 continue;
1799 case 'r':
1800 cvq |= cvq_r;
1801 continue;
1802 case 'A':
1803 if (!(cvq & cvq_A))
1805 cvq |= cvq_A;
1806 iter_array = iter;
1808 cvq += cvq_A_cnt;
1809 break;
1810 case 'M':
1811 if (cvq)
1813 decode_KVrA(prefix, postfix, cvq, iter_array);
1814 cvq = 0;
1816 prefix += " ";
1817 prefix += (*iter).get_optional_type();
1818 prefix += "::*";
1819 break;
1820 case 'U':
1821 if (cvq)
1823 decode_KVrA(prefix, postfix, cvq, iter_array);
1824 cvq = 0;
1826 prefix += " ";
1827 prefix += (*iter).get_optional_type();
1828 break;
1829 case 'G': // Only here so we added a substitution.
1830 break;
1832 break;
1835 if (cvq)
1836 decode_KVrA(prefix, postfix, cvq|cvq_last, iter_array);
1837 M_printing_suppressed = false;
1838 _GLIBCXX_DEMANGLER_RETURN3;
1842 template<typename Allocator>
1843 bool
1844 session<Allocator>::decode_type_with_postfix(
1845 string_type& prefix, string_type& postfix,
1846 qualifier_list<Allocator>* qualifiers)
1848 _GLIBCXX_DEMANGLER_DOUT_ENTERING2("decode_type");
1849 ++M_inside_type;
1850 bool recursive_template_param_or_substitution_call;
1851 if (!(recursive_template_param_or_substitution_call = qualifiers))
1852 qualifiers = new qualifier_list<Allocator>(*this);
1853 // First eat all qualifiers.
1854 bool failure = false;
1855 for(;;) // So we can use 'continue' to eat the next qualifier.
1857 int start_pos = M_pos;
1858 switch(current())
1860 case 'P':
1861 qualifiers->add_qualifier_start(pointer, start_pos,
1862 M_inside_substitution);
1863 eat_current();
1864 continue;
1865 case 'R':
1866 qualifiers->add_qualifier_start(reference, start_pos,
1867 M_inside_substitution);
1868 eat_current();
1869 continue;
1870 case 'K':
1871 case 'V':
1872 case 'r':
1874 char c;
1875 int count = 0;
1878 ++count;
1879 c = next();
1881 while(c == 'K' || c == 'V' || c == 'r');
1882 qualifiers->add_qualifier_start(cv_qualifier, start_pos, count,
1883 M_inside_substitution);
1884 continue;
1886 case 'U':
1888 eat_current();
1889 string_type source_name;
1890 if (!decode_source_name(source_name))
1892 failure = true;
1893 break;
1895 qualifiers->add_qualifier_start(vendor_extension, start_pos,
1896 source_name, M_inside_substitution);
1897 continue;
1899 case 'A':
1901 // <array-type> ::= A <positive dimension number> _ <element type>
1902 // ::= A [<dimension expression>] _ <element type>
1904 string_type index;
1905 int saved_pos;
1906 store(saved_pos);
1907 if (next() == 'n' || !decode_number(index))
1909 restore(saved_pos);
1910 if (next() != '_' && !decode_expression(index))
1912 failure = true;
1913 break;
1916 if (eat_current() != '_')
1918 failure = true;
1919 break;
1921 qualifiers->add_qualifier_start(array, start_pos, index,
1922 M_inside_substitution);
1923 continue;
1925 case 'M':
1927 // <pointer-to-member-type> ::= M <class type> <member type>
1928 // <Q>M<C> or <Q>M<C><Q2>F<R><B>E
1929 eat_current();
1930 string_type class_type;
1931 if (!decode_type(class_type)) // Substitution: "<C>".
1933 failure = true;
1934 break;
1936 char c = current();
1937 if (c == 'F' || c == 'K' || c == 'V' || c == 'r')
1938 // Must be CV-qualifiers and a member function pointer.
1940 // <Q>M<C><Q2>F<R><B>E ==> R (C::*Q)B Q2
1941 // substitutions: "<C>", "F<R><B>E" (<R> and <B>
1942 // recursive), "M<C><Q2>F<R><B>E".
1943 int count = 0;
1944 int Q2_start_pos = M_pos;
1945 while(c == 'K' || c == 'V' || c == 'r') // Decode <Q2>.
1947 ++count;
1948 c = next();
1950 qualifier_list<Allocator> class_type_qualifiers(*this);
1951 if (count)
1952 class_type_qualifiers.
1953 add_qualifier_start(cv_qualifier, Q2_start_pos,
1954 count, M_inside_substitution);
1955 string_type member_function_qualifiers;
1956 // It is unclear why g++ doesn't add a substitution for
1957 // "<Q2>F<R><B>E" as it should I think.
1958 string_type member_function_qualifiers_postfix;
1959 class_type_qualifiers.
1960 decode_qualifiers(member_function_qualifiers,
1961 member_function_qualifiers_postfix, true);
1962 member_function_qualifiers +=
1963 member_function_qualifiers_postfix;
1964 // I don't think this substitution is actually ever used.
1965 int function_pos = M_pos;
1966 if (eat_current() != 'F')
1968 failure = true;
1969 break;
1971 // Return type.
1972 // Constructors, destructors and conversion operators don't
1973 // have a return type, but seem to never get here.
1974 string_type return_type_postfix;
1975 if (!decode_type_with_postfix(prefix, return_type_postfix))
1976 // substitution: <R> recursive
1978 failure = true;
1979 break;
1981 prefix += " (";
1982 prefix += class_type;
1983 prefix += "::*";
1984 string_type bare_function_type;
1985 if (!decode_bare_function_type(bare_function_type)
1986 || eat_current() != 'E') // Substitution: <B> recursive.
1988 failure = true;
1989 break;
1991 // substitution: "F<R><B>E".
1992 add_substitution(function_pos, type);
1993 // substitution: "M<C><Q2>F<R><B>E".
1994 add_substitution(start_pos, type);
1995 // substitution: all qualified types if any.
1996 qualifiers->decode_qualifiers(prefix, postfix);
1997 postfix += ")";
1998 postfix += bare_function_type;
1999 postfix += member_function_qualifiers;
2000 postfix += return_type_postfix;
2001 goto decode_type_exit;
2003 qualifiers->add_qualifier_start(pointer_to_member, start_pos,
2004 class_type, M_inside_substitution);
2005 continue;
2007 default:
2008 break;
2010 break;
2012 if (!failure)
2014 // <Q>G<T> ==> imaginary T Q
2015 // substitutions: "<T>", "G<T>" (<T> recursive).
2016 // <Q>C<T> ==> complex T Q
2017 // substitutions: "<T>", "C<T>" (<T> recursive).
2018 if (current() == 'C' || current() == 'G')
2020 prefix += current() == 'C' ? "complex " : "imaginary ";
2021 qualifiers->add_qualifier_start(complex_or_imaginary, M_pos,
2022 M_inside_substitution);
2023 eat_current();
2025 int start_pos = M_pos;
2026 switch(current())
2028 case 'F':
2030 // <function-type> ::= F [Y] <bare-function-type> E
2032 // Note that g++ never generates the 'Y', but we try to
2033 // demangle it anyway.
2034 bool extern_C = (next() == 'Y');
2035 if (extern_C)
2036 eat_current();
2038 // <Q>F<R><B>E ==> R (Q)B
2039 // substitution: "<R>", "<B>" (<B> recursive) and "F<R><B>E".
2041 // Return type.
2042 string_type return_type_postfix;
2043 if (!decode_type_with_postfix(prefix, return_type_postfix))
2044 // Substitution: "<R>".
2046 failure = true;
2047 break;
2049 // Only array and function (pointer) types have a postfix.
2050 // In that case we don't want the space but expect something
2051 // like prefix is "int (*" and postfix is ") [1]".
2052 // We do want the space if this pointer is qualified.
2053 if (return_type_postfix.size() == 0 ||
2054 (prefix.size() > 0 && *prefix.rbegin() != '*'))
2055 prefix += ' ';
2056 prefix += '(';
2057 string_type bare_function_type;
2058 if (!decode_bare_function_type(bare_function_type)
2059 // substitution: "<B>" (<B> recursive).
2060 || eat_current() != 'E')
2062 failure = true;
2063 break;
2065 add_substitution(start_pos, type); // Substitution: "F<R><B>E".
2066 qualifiers->decode_qualifiers(prefix, postfix);
2067 // substitution: all qualified types, if any.
2068 postfix += ")";
2069 if (extern_C)
2070 postfix += " [extern \"C\"] ";
2071 postfix += bare_function_type;
2072 postfix += return_type_postfix;
2073 break;
2075 case 'T':
2076 if (!decode_template_param(prefix, qualifiers))
2078 failure = true;
2079 break;
2081 if (current() == 'I')
2083 add_substitution(start_pos, template_template_param);
2084 // substitution: "<template-template-param>".
2085 if (!decode_template_args(prefix))
2087 failure = true;
2088 break;
2091 if (!recursive_template_param_or_substitution_call
2092 && qualifiers->suppressed())
2094 add_substitution(start_pos, type);
2095 // substitution: "<template-param>" or
2096 // "<template-template-param> <template-args>".
2097 qualifiers->decode_qualifiers(prefix, postfix);
2098 // substitution: all qualified types, if any.
2100 break;
2101 case 'S':
2102 if (M_pos >= M_maxpos)
2104 failure = true;
2105 break;
2107 if (M_str[M_pos + 1] != 't')
2109 if (!decode_substitution(prefix, qualifiers))
2111 failure = true;
2112 break;
2114 if (current() == 'I')
2116 if (!decode_template_args(prefix))
2118 failure = true;
2119 break;
2121 if (!recursive_template_param_or_substitution_call
2122 && qualifiers->suppressed())
2123 add_substitution(start_pos, type);
2124 // Substitution:
2125 // "<template-template-param> <template-args>".
2127 if (!recursive_template_param_or_substitution_call
2128 && qualifiers->suppressed())
2129 qualifiers->decode_qualifiers(prefix, postfix);
2130 // Substitution: all qualified types, if any.
2131 break;
2133 /* Fall-through for St */
2134 case 'N':
2135 case 'Z':
2136 case '0':
2137 case '1':
2138 case '2':
2139 case '3':
2140 case '4':
2141 case '5':
2142 case '6':
2143 case '7':
2144 case '8':
2145 case '9':
2146 // <Q><T> ==> T Q
2147 // substitutions: "<T>" (<T> recursive).
2148 if (!decode_class_enum_type(prefix))
2150 failure = true;
2151 break;
2153 if (!recursive_template_param_or_substitution_call)
2155 add_substitution(start_pos, type);
2156 // substitution: "<class-enum-type>".
2157 qualifiers->decode_qualifiers(prefix, postfix);
2158 // substitution: all qualified types, if any.
2160 else
2161 qualifiers->printing_suppressed();
2162 break;
2163 default:
2164 // <Q><T> ==> T Q
2165 // substitutions: "<T>" (<T> recursive).
2166 if (!decode_builtin_type(prefix))
2168 failure = true;
2169 break;
2171 // If decode_type was called from decode_template_param then we
2172 // need to suppress calling qualifiers here in order to get a
2173 // substitution added anyway (for the <template-param>).
2174 if (!recursive_template_param_or_substitution_call)
2175 qualifiers->decode_qualifiers(prefix, postfix);
2176 else
2177 qualifiers->printing_suppressed();
2178 break;
2181 decode_type_exit:
2182 --M_inside_type;
2183 if (!recursive_template_param_or_substitution_call)
2184 delete qualifiers;
2185 if (failure)
2186 _GLIBCXX_DEMANGLER_FAILURE;
2187 _GLIBCXX_DEMANGLER_RETURN2;
2190 // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
2191 // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
2193 // <prefix> ::= <prefix> <unqualified-name>
2194 // ::= <template-prefix> <template-args>
2195 // ::= <template-param>
2196 // ::= # empty
2197 // ::= <substitution>
2199 // <template-prefix> ::= <prefix> <template unqualified-name>
2200 // ::= <template-param>
2201 // ::= <substitution>
2203 template<typename Allocator>
2204 bool
2205 session<Allocator>::decode_nested_name(string_type& output,
2206 string_type& qualifiers)
2208 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_nested_name");
2210 if (current() != 'N' || M_pos >= M_maxpos)
2211 _GLIBCXX_DEMANGLER_FAILURE;
2213 // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const
2214 char const* qualifiers_start = &M_str[M_pos + 1];
2215 for (char c = next(); c == 'K' || c == 'V' || c == 'r'; c = next());
2216 for (char const* qualifier_ptr = &M_str[M_pos - 1];
2217 qualifier_ptr >= qualifiers_start; --qualifier_ptr)
2218 switch(*qualifier_ptr)
2220 case 'K':
2221 qualifiers += " const";
2222 break;
2223 case 'V':
2224 qualifiers += " volatile";
2225 break;
2226 case 'r':
2227 qualifiers += " restrict";
2228 break;
2231 int number_of_prefixes = 0;
2232 int substitution_start = M_pos;
2233 for(;;)
2235 ++number_of_prefixes;
2236 if (current() == 'S')
2238 if (!decode_substitution(output))
2239 _GLIBCXX_DEMANGLER_FAILURE;
2241 else if (current() == 'I')
2243 if (!decode_template_args(output))
2244 _GLIBCXX_DEMANGLER_FAILURE;
2245 if (current() != 'E')
2247 // substitution: "<template-prefix> <template-args>".
2248 add_substitution(substitution_start, nested_name_prefix,
2249 number_of_prefixes);
2252 else
2254 if (current() == 'T')
2256 if (!decode_template_param(output))
2257 _GLIBCXX_DEMANGLER_FAILURE;
2259 else if (!decode_unqualified_name(output))
2260 _GLIBCXX_DEMANGLER_FAILURE;
2261 if (current() != 'E')
2263 // substitution: "<prefix> <unqualified-name>" or
2264 // "<prefix> <template unqualified-name>".
2265 add_substitution(substitution_start,
2266 (current() == 'I') ? nested_name_template_prefix
2267 : nested_name_prefix,
2268 number_of_prefixes);
2271 if (current() == 'E')
2273 eat_current();
2274 _GLIBCXX_DEMANGLER_RETURN;
2276 if (current() != 'I')
2277 output += "::";
2278 else if (M_template_args_need_space)
2279 output += ' ';
2280 M_template_args_need_space = false;
2282 _GLIBCXX_DEMANGLER_FAILURE;
2285 // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2286 // := Z <function encoding> E s [<discriminator>]
2287 // <discriminator> := _ <non-negative number>
2289 template<typename Allocator>
2290 bool
2291 session<Allocator>::decode_local_name(string_type& output)
2293 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_local_name");
2294 if (current() != 'Z' || M_pos >= M_maxpos)
2295 _GLIBCXX_DEMANGLER_FAILURE;
2296 if ((M_pos += decode_encoding(output, M_str + M_pos + 1,
2297 M_maxpos - M_pos, M_implementation_details) + 1) < 0 ||
2298 eat_current() != 'E')
2299 _GLIBCXX_DEMANGLER_FAILURE;
2300 output += "::";
2301 if (current() == 's')
2303 eat_current();
2304 output += "string literal";
2306 else
2308 string_type nested_name_qualifiers;
2309 if (!decode_name(output, nested_name_qualifiers))
2310 _GLIBCXX_DEMANGLER_FAILURE;
2311 output += nested_name_qualifiers;
2313 string_type discriminator;
2314 if (current() == '_' && next() != 'n' && !decode_number(discriminator))
2315 _GLIBCXX_DEMANGLER_FAILURE;
2316 _GLIBCXX_DEMANGLER_RETURN;
2319 // <source-name> ::= <positive length number> <identifier>
2321 template<typename Allocator>
2322 bool
2323 session<Allocator>::decode_source_name(string_type& output)
2325 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_source_name");
2326 int length = current() - '0';
2327 if (length < 1 || length > 9)
2328 _GLIBCXX_DEMANGLER_FAILURE;
2329 while(isdigit(next()))
2330 length = 10 * length + current() - '0';
2331 char const* ptr = &M_str[M_pos];
2332 if (length > 11 && !strncmp(ptr, "_GLOBAL_", 8) && ptr[9] == 'N'
2333 && ptr[8] == ptr[10])
2335 output += "(anonymous namespace)";
2336 if ((M_pos += length) > M_maxpos + 1)
2337 _GLIBCXX_DEMANGLER_FAILURE;
2339 else
2340 while(length--)
2342 if (current() == 0)
2343 _GLIBCXX_DEMANGLER_FAILURE;
2344 output += eat_current();
2346 _GLIBCXX_DEMANGLER_RETURN;
2349 // <unqualified-name> ::= <operator-name> # Starts with lower case.
2350 // ::= <ctor-dtor-name> # Starts with 'C' or 'D'.
2351 // ::= <source-name> # Starts with a digit.
2353 template<typename Allocator>
2354 bool
2355 session<Allocator>::decode_unqualified_name(string_type& output)
2357 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_unqualified_name");
2358 if (M_inside_template_args)
2360 if (!decode_source_name(output))
2361 _GLIBCXX_DEMANGLER_FAILURE;
2363 else if (isdigit(current()))
2365 bool recursive_unqualified_name = (&M_function_name == &output);
2366 // This can be a recursive call when we are decoding
2367 // an <operator-name> that is a cast operator for a some
2368 // <unqualified-name>; for example "operator Foo()".
2369 // In that case this is thus not a ctor or dtor and we
2370 // are not interested in updating M_function_name.
2371 if (!recursive_unqualified_name)
2372 M_function_name.clear();
2373 M_name_is_template = false;
2374 M_name_is_cdtor = false;
2375 M_name_is_conversion_operator = false;
2376 if (!decode_source_name(M_function_name))
2377 _GLIBCXX_DEMANGLER_FAILURE;
2378 if (!recursive_unqualified_name)
2379 output += M_function_name;
2381 else if (islower(current()))
2383 M_function_name.clear();
2384 M_name_is_template = false;
2385 M_name_is_cdtor = false;
2386 M_name_is_conversion_operator = false;
2387 if (!decode_operator_name(M_function_name))
2388 _GLIBCXX_DEMANGLER_FAILURE;
2389 output += M_function_name;
2391 else if (current() == 'C' || current() == 'D')
2393 // <ctor-dtor-name> ::=
2394 // C1 # complete object (in-charge) constructor
2395 // C2 # base object (not-in-charge) constructor
2396 // C3 # complete object (in-charge) allocating constructor
2397 // D0 # deleting (in-charge) destructor
2398 // D1 # complete object (in-charge) destructor
2399 // D2 # base object (not-in-charge) destructor
2401 if (current() == 'C')
2403 char c = next();
2404 if (c < '1' || c > '3')
2405 _GLIBCXX_DEMANGLER_FAILURE;
2407 else
2409 char c = next();
2410 if (c < '0' || c > '2')
2411 _GLIBCXX_DEMANGLER_FAILURE;
2412 output += '~';
2413 M_saw_destructor = true;
2415 M_name_is_cdtor = true;
2416 eat_current();
2417 output += M_function_name;
2419 else
2420 _GLIBCXX_DEMANGLER_FAILURE;
2421 _GLIBCXX_DEMANGLER_RETURN;
2424 // <unscoped-name> ::=
2425 // <unqualified-name> # Starts not with an 'S'
2426 // St <unqualified-name> # ::std::
2428 template<typename Allocator>
2429 bool
2430 session<Allocator>::decode_unscoped_name(string_type& output)
2432 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_unscoped_name");
2433 if (current() == 'S')
2435 if (next() != 't')
2436 _GLIBCXX_DEMANGLER_FAILURE;
2437 eat_current();
2438 output += "std::";
2440 decode_unqualified_name(output);
2441 _GLIBCXX_DEMANGLER_RETURN;
2444 // <name> ::=
2445 // <nested-name> # Starts with 'N'
2446 // <unscoped-template-name> <template-args> # idem
2447 // <local-name> # Starts with 'Z'
2448 // <unscoped-name> # Starts with 'S', 'C', 'D',
2449 // # a digit or a lower case
2450 // # character.
2452 // <unscoped-template-name> ::= <unscoped-name>
2453 // ::= <substitution>
2454 template<typename Allocator>
2455 bool
2456 session<Allocator>::decode_name(string_type& output,
2457 string_type& nested_name_qualifiers)
2459 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_name");
2460 int substitution_start = M_pos;
2461 if (current() == 'S' && (M_pos >= M_maxpos || M_str[M_pos + 1] != 't'))
2463 if (!decode_substitution(output))
2464 _GLIBCXX_DEMANGLER_FAILURE;
2466 else if (current() == 'N')
2468 decode_nested_name(output, nested_name_qualifiers);
2469 _GLIBCXX_DEMANGLER_RETURN;
2471 else if (current() == 'Z')
2473 decode_local_name(output);
2474 _GLIBCXX_DEMANGLER_RETURN;
2476 else if (!decode_unscoped_name(output))
2477 _GLIBCXX_DEMANGLER_FAILURE;
2478 if (current() == 'I')
2480 // Must have been an <unscoped-template-name>.
2481 add_substitution(substitution_start, unscoped_template_name);
2482 if (!decode_template_args(output))
2483 _GLIBCXX_DEMANGLER_FAILURE;
2485 M_template_args_need_space = false;
2486 _GLIBCXX_DEMANGLER_RETURN;
2489 // <call-offset> ::= h <nv-offset> _
2490 // ::= v <v-offset> _
2491 // <nv-offset> ::= <offset number>
2492 // non-virtual base override
2494 // <v-offset> ::= <offset number> _ <virtual offset number>
2495 // virtual base override, with vcall offset
2496 template<typename Allocator>
2497 bool
2498 session<Allocator>::decode_call_offset(string_type&
2499 #if _GLIBCXX_DEMANGLER_CWDEBUG
2500 output
2501 #endif
2504 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_call_offset");
2505 if (current() == 'h')
2507 string_type dummy;
2508 eat_current();
2509 if (decode_number(dummy) && current() == '_')
2511 eat_current();
2512 _GLIBCXX_DEMANGLER_RETURN;
2515 else if (current() == 'v')
2517 string_type dummy;
2518 eat_current();
2519 if (decode_number(dummy) && current() == '_')
2521 eat_current();
2522 if (decode_number(dummy) && current() == '_')
2524 eat_current();
2525 _GLIBCXX_DEMANGLER_RETURN;
2529 _GLIBCXX_DEMANGLER_FAILURE;
2533 // <special-name> ::=
2534 // TV <type> # virtual table
2535 // TT <type> # VTT structure (construction
2536 // vtable index).
2537 // TI <type> # typeinfo structure
2538 // TS <type> # typeinfo name (null-terminated
2539 // byte string).
2540 // GV <object name> # Guard variable for one-time
2541 // initialization of static objects in
2542 // a local scope.
2543 // T <call-offset> <base encoding># base is the nominal target function
2544 // of thunk.
2545 // Tc <call-offset> <call-offset> <base encoding> # base is the nominal
2546 // target function of thunk; first
2547 // call-offset is 'this' adjustment;
2548 // second call-offset is result
2549 // adjustment
2551 template<typename Allocator>
2552 bool
2553 session<Allocator>::decode_special_name(string_type& output)
2555 _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_special_name");
2556 if (current() == 'G')
2558 if (next() != 'V')
2559 _GLIBCXX_DEMANGLER_FAILURE;
2560 output += "guard variable for ";
2561 string_type nested_name_qualifiers;
2562 eat_current();
2563 if (!decode_name(output, nested_name_qualifiers))
2564 _GLIBCXX_DEMANGLER_FAILURE;
2565 output += nested_name_qualifiers;
2566 _GLIBCXX_DEMANGLER_RETURN;
2568 else if (current() != 'T')
2569 _GLIBCXX_DEMANGLER_FAILURE;
2570 switch(next())
2572 case 'V':
2573 output += "vtable for ";
2574 eat_current();
2575 decode_type(output);
2576 _GLIBCXX_DEMANGLER_RETURN;
2577 case 'T':
2578 output += "VTT for ";
2579 eat_current();
2580 decode_type(output);
2581 _GLIBCXX_DEMANGLER_RETURN;
2582 case 'I':
2583 output += "typeinfo for ";
2584 eat_current();
2585 decode_type(output);
2586 _GLIBCXX_DEMANGLER_RETURN;
2587 case 'S':
2588 output += "typeinfo name for ";
2589 eat_current();
2590 decode_type(output);
2591 _GLIBCXX_DEMANGLER_RETURN;
2592 case 'c':
2593 output += "covariant return thunk to ";
2594 if (!decode_call_offset(output)
2595 || !decode_call_offset(output)
2596 || (M_pos += decode_encoding(output, M_str + M_pos,
2597 M_maxpos - M_pos + 1, M_implementation_details)) < 0)
2598 _GLIBCXX_DEMANGLER_FAILURE;
2599 _GLIBCXX_DEMANGLER_RETURN;
2600 case 'C': // GNU extension?
2602 string_type first;
2603 output += "construction vtable for ";
2604 eat_current();
2605 if (!decode_type(first))
2606 _GLIBCXX_DEMANGLER_FAILURE;
2607 while(isdigit(current()))
2608 eat_current();
2609 if (eat_current() != '_')
2610 _GLIBCXX_DEMANGLER_FAILURE;
2611 if (!decode_type(output))
2612 _GLIBCXX_DEMANGLER_FAILURE;
2613 output += "-in-";
2614 output += first;
2615 _GLIBCXX_DEMANGLER_RETURN;
2617 default:
2618 if (current() == 'v')
2619 output += "virtual thunk to ";
2620 else
2621 output += "non-virtual thunk to ";
2622 if (!decode_call_offset(output)
2623 || (M_pos += decode_encoding(output, M_str + M_pos,
2624 M_maxpos - M_pos + 1, M_implementation_details)) < 0)
2625 _GLIBCXX_DEMANGLER_FAILURE;
2626 _GLIBCXX_DEMANGLER_RETURN;
2630 // <encoding> ::=
2631 // <function name> <bare-function-type> # Starts with 'C', 'D', 'N',
2632 // 'S', a digit or a lower case
2633 // character.
2634 // <data name> # Idem.
2635 // <special-name> # Starts with 'T' or 'G'.
2636 template<typename Allocator>
2638 session<Allocator>::decode_encoding(string_type& output,
2639 char const* in, int len, implementation_details const& id)
2641 #if _GLIBCXX_DEMANGLER_CWDEBUG
2642 _GLIBCXX_DEMANGLER_DOUT(dc::demangler,
2643 "Output thus far: \"" << output << '"');
2644 string_type input(in, len > 0x40000000 ? strlen(in) : len);
2645 _GLIBCXX_DEMANGLER_DOUT(
2646 dc::demangler, "Entering decode_encoding(\"" << input << "\")");
2647 #endif
2648 if (len <= 0)
2649 return INT_MIN;
2650 session<Allocator> demangler_session(in, len, id);
2651 string_type nested_name_qualifiers;
2652 int saved_pos;
2653 demangler_session.store(saved_pos);
2654 if (demangler_session.decode_special_name(output))
2655 return demangler_session.M_pos;
2656 demangler_session.restore(saved_pos);
2657 string_type name;
2658 if (!demangler_session.decode_name(name, nested_name_qualifiers))
2659 return INT_MIN;
2660 if (demangler_session.current() == 0
2661 || demangler_session.current() == 'E')
2663 output += name;
2664 output += nested_name_qualifiers;
2665 return demangler_session.M_pos;
2667 // Must have been a <function name>.
2668 string_type return_type_postfix;
2669 if (demangler_session.M_name_is_template
2670 && !(demangler_session.M_name_is_cdtor
2671 || demangler_session.M_name_is_conversion_operator))
2673 // Return type of function
2674 if (!demangler_session.decode_type_with_postfix(output,
2675 return_type_postfix))
2676 return INT_MIN;
2677 output += ' ';
2679 output += name;
2680 if (!demangler_session.decode_bare_function_type(output))
2681 return INT_MIN;
2682 output += nested_name_qualifiers;
2683 output += return_type_postfix;
2684 return demangler_session.M_pos;
2687 } // namespace demangler
2689 // Public interface
2690 template<typename Allocator>
2691 struct demangle
2693 typedef typename Allocator::template rebind<char>::other char_Allocator;
2694 typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
2695 string_type;
2696 static string_type symbol(char const* in,
2697 demangler::implementation_details const& id);
2698 static string_type type(char const* in,
2699 demangler::implementation_details const& id);
2702 // demangle::symbol()
2704 // Demangle `input' which should be a mangled function name as for
2705 // instance returned by nm(1).
2706 template<typename Allocator>
2707 typename demangle<Allocator>::string_type
2708 demangle<Allocator>::symbol(char const* input,
2709 demangler::implementation_details const& id)
2711 // <mangled-name> ::= _Z <encoding>
2712 // <mangled-name> ::= _GLOBAL_ _<type>_ <disambiguation part>
2713 // <type> can be I or D (GNU extension)
2714 typedef demangler::session<Allocator> demangler_type;
2715 string_type result;
2716 bool failure = (input[0] != '_');
2718 if (!failure)
2720 if (input[1] == 'G')
2722 if (!strncmp(input, "_GLOBAL__", 9)
2723 && (input[9] == 'D' || input[9] == 'I')
2724 && input[10] == '_')
2726 if (input[9] == 'D')
2727 result.assign("global destructors keyed to ", 28);
2728 else
2729 result.assign("global constructors keyed to ", 29);
2730 // Output the disambiguation part as-is.
2731 result += input + 11;
2733 else
2734 failure = true;
2736 else if (input[1] == 'Z')
2738 int cnt =
2739 demangler_type::decode_encoding(result, input + 2, INT_MAX, id);
2740 if (cnt < 0 || input[cnt + 2] != 0)
2741 failure = true;
2743 else
2744 failure = true;
2747 // Failure to demangle, return the mangled name.
2748 if (failure)
2749 result.assign(input, strlen(input));
2751 return result;
2754 // demangle::type()
2755 // Demangle `input' which must be a zero terminated mangled type
2756 // name as for instance returned by std::type_info::name().
2757 template<typename Allocator>
2758 typename demangle<Allocator>::string_type
2759 demangle<Allocator>::type(char const* input,
2760 demangler::implementation_details const& id)
2762 std::basic_string<char, std::char_traits<char>, Allocator> result;
2763 if (input == NULL)
2764 result = "(null)";
2765 else
2767 demangler::session<Allocator> demangler_session(input, INT_MAX, id);
2768 if (!demangler_session.decode_type(result)
2769 || demangler_session.remaining_input_characters())
2771 // Failure to demangle, return the mangled name.
2772 result = input;
2775 return result;
2778 } // namespace __gnu_cxx
2780 #endif // __DEMANGLE_H