]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libstdc++/include/ext/demangle.h
This commit was generated by cvs2svn to compensate for changes in r156251,
[FreeBSD/FreeBSD.git] / contrib / libstdc++ / include / ext / demangle.h
1 // C++ IA64 / g++ v3 demangler  -*- C++ -*-
2
3 // Copyright (C) 2003, 2004 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.
11
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.
16
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.
21
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.
30
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
34
35 #ifndef _DEMANGLER_H
36 #define _DEMANGLER_H 1
37
38 #include <vector>
39 #include <string>
40 #include <ext/new_allocator.h>
41
42 #ifndef _GLIBCXX_DEMANGLER_DEBUG
43 #define _GLIBCXX_DEMANGLER_CWDEBUG 0
44 #define _GLIBCXX_DEMANGLER_DEBUG(x)
45 #define _GLIBCXX_DEMANGLER_DOUT(cntrl, data)
46 #define _GLIBCXX_DEMANGLER_DOUT_ENTERING(x)
47 #define _GLIBCXX_DEMANGLER_DOUT_ENTERING2(x)
48 #define _GLIBCXX_DEMANGLER_DOUT_ENTERING3(x)
49 #define _GLIBCXX_DEMANGLER_RETURN return M_result
50 #define _GLIBCXX_DEMANGLER_RETURN2 return M_result
51 #define _GLIBCXX_DEMANGLER_RETURN3
52 #define _GLIBCXX_DEMANGLER_FAILURE \
53     do { M_result = false; return false; } while(0)
54 #else
55 #define _GLIBCXX_DEMANGLER_CWDEBUG 1
56 #endif
57
58 namespace __gnu_cxx
59 {
60   namespace demangler
61   {
62     enum substitution_nt
63     {
64       type,
65       template_template_param,
66       nested_name_prefix,
67       nested_name_template_prefix,
68       unscoped_template_name
69     };
70
71     struct substitution_st
72     {
73       int M_start_pos;
74       substitution_nt M_type;
75       int M_number_of_prefixes;
76
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       { }
83     };
84
85     enum simple_qualifier_nt
86     {
87       complex_or_imaginary = 'G',
88       pointer = 'P',
89       reference = 'R'
90     };
91
92     enum cv_qualifier_nt
93     {
94       cv_qualifier = 'K'
95     };
96
97     enum param_qualifier_nt
98     {
99       vendor_extension = 'U',
100       array = 'A',
101       pointer_to_member = 'M'
102     };
103
104     template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> >
105       class qualifier;
106
107     template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> >
108       class qualifier_list;
109
110     template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> >
111       class session;
112
113     template<typename Tp, typename Allocator>
114       class qualifier
115       {
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;
120
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;
129
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)
137         { }
138
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)
149         { }
150
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)
159         { }
160
161         int
162         get_start_pos(void) const
163         { return M_start_pos; }
164
165         char
166         first_qualifier(void) const
167         { M_cnt = 1; return M_qualifier1; }
168
169         char
170         next_qualifier(void) const
171         {
172           return (++M_cnt == 2) ? M_qualifier2
173                                 : ((M_cnt == 3) ? M_qualifier3 : 0);
174         }
175
176         string_type const&
177         get_optional_type(void) const
178         { return M_optional_type; }
179
180         bool
181         part_of_substitution(void) const
182         { return M_part_of_substitution; }
183
184 #if _GLIBCXX_DEMANGLER_CWDEBUG
185         friend std::ostream& operator<<(std::ostream& os, qualifier const& qual)
186         {
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')
195           {
196             if (qual.M_qualifier2)
197             {
198               os << (char)qual.M_qualifier2;
199               if (qual.M_qualifier3)
200                 os << (char)qual.M_qualifier3;
201             }
202           }
203           return os;
204         }
205 #endif
206       };
207
208     template<typename Tp, typename Allocator>
209       class qualifier_list
210       {
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;
215
216       private:
217         mutable bool M_printing_suppressed;
218         typedef qualifier<Tp, 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<Tp, Allocator>& M_demangler;
223
224         void decode_KVrA(string_type& prefix, string_type& postfix, int cvq,
225                          typename qual_vector::
226                            const_reverse_iterator const& iter_array) const;
227
228       public:
229         qualifier_list(session<Tp, Allocator>& demangler_obj)
230         : M_printing_suppressed(false), M_demangler(demangler_obj)
231         { }
232
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<Tp, Allocator>(start_pos,
239                   simple_qualifier, inside_substitution)); }
240
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<Tp, Allocator>(start_pos,
248                     cv_qualifier, &M_demangler.M_str[start_pos],
249                     count, inside_substitution)); }
250
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<Tp, Allocator>(start_pos,
258                     param_qualifier, optional_type, inside_substitution)); }
259
260         void
261         decode_qualifiers(string_type& prefix,
262                           string_type& postfix,
263                           bool member_function_pointer_qualifiers) const;
264
265         bool
266         suppressed(void) const
267         { return M_printing_suppressed; }
268
269         void
270         printing_suppressed(void)
271         { M_printing_suppressed = true; }
272
273         size_t
274         size(void) const
275         { return M_qualifier_starts.size(); }
276
277 #if _GLIBCXX_DEMANGLER_CWDEBUG
278         friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list)
279         {
280           typename qual_vector::const_iterator
281               iter = list.M_qualifier_starts.begin();
282           if (iter != list.M_qualifier_starts.end())
283           {
284             os << "{ " << *iter;
285             while (++iter != list.M_qualifier_starts.end())
286               os << ", " << *iter;
287             os << " }";
288           }
289           else
290             os << "{ }";
291           return os;
292         }
293 #endif
294       };
295
296     struct implementation_details
297     {
298       private:
299         unsigned int M_style;
300
301       public:
302         // The following flags change the behaviour of the demangler.  The
303         // default behaviour is that none of these flags is set.
304
305         static unsigned int const style_void = 1;
306         // Default behaviour:                           int f()
307         // Use (void) instead of ():                    int f(void)
308
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
314
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
319
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)
324
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)
329
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; }
348     };
349
350     template<typename Tp, typename Allocator>
351       class session
352       {
353       public:
354         friend class qualifier_list<Tp, Allocator>;
355         typedef typename Allocator::template rebind<char>::other
356             char_Allocator;
357         typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
358             string_type;
359
360       private:
361         char const* M_str;
362         int M_pos;
363         int M_maxpos;
364         bool M_result;
365         int M_inside_template_args;
366         int M_inside_type;
367         int M_inside_substitution;
368         bool M_saw_destructor;
369         bool M_name_is_cdtor;
370         bool M_name_is_template;
371         bool M_name_is_conversion_operator;
372         bool M_template_args_need_space;
373         string_type M_function_name;
374         typedef typename Allocator::template rebind<int>::other
375                 int_Allocator;
376         typedef typename Allocator::template rebind<substitution_st>::other
377                 subst_Allocator;
378         std::vector<int, int_Allocator> M_template_arg_pos;
379         int M_template_arg_pos_offset;
380         std::vector<substitution_st, subst_Allocator> M_substitutions_pos;
381         implementation_details const& M_implementation_details;
382         typedef typename Allocator::template
383             rebind<qualifier_list<Allocator> >::other qualifier_list_Allocator;
384         qualifier_list_Allocator M_qualifier_list_alloc;
385 #if _GLIBCXX_DEMANGLER_CWDEBUG
386         bool M_inside_add_substitution;
387 #endif
388
389       public:
390         explicit session(char const* in, int len,
391             implementation_details const& id = implementation_details())
392         : M_str(in), M_pos(0), M_maxpos(len - 1), M_result(true),
393           M_inside_template_args(0), M_inside_type(0),
394           M_inside_substitution(0), M_saw_destructor(false),
395           M_name_is_cdtor(false), M_name_is_template(false),
396           M_name_is_conversion_operator(false),
397           M_template_args_need_space(false), M_template_arg_pos_offset(0),
398           M_implementation_details(id)
399 #if _GLIBCXX_DEMANGLER_CWDEBUG
400           , M_inside_add_substitution(false)
401 #endif
402         { }
403
404         static int
405         decode_encoding(string_type& output, char const* input, int len,
406           implementation_details const& id = implementation_details());
407
408         bool
409         decode_type(string_type& output,
410                     qualifier_list<Tp, Allocator>* qualifiers = NULL)
411         {
412           string_type postfix;
413           bool res = decode_type_with_postfix(output, postfix, qualifiers);
414           output += postfix;
415           return res;
416         }
417
418         bool
419         remaining_input_characters(void) const
420         { return current() != 0; }
421
422       private:
423         char
424         current(void) const
425         { return (M_pos > M_maxpos) ? 0 : M_str[M_pos]; }
426
427         char
428         next_peek(void) const
429         { return (M_pos >= M_maxpos) ? 0 : M_str[M_pos + 1]; }
430
431         char
432         next(void)
433         { return (M_pos >= M_maxpos) ? 0 : M_str[++M_pos]; }
434
435         char
436         eat_current(void)
437         { return (M_pos > M_maxpos) ? 0 : M_str[M_pos++]; }
438
439         void
440         store(int& saved_pos)
441         { saved_pos = M_pos; }
442
443         void
444         restore(int saved_pos)
445         { M_pos = saved_pos; M_result = true; }
446
447         void
448         add_substitution(int start_pos,
449                          substitution_nt sub_type,
450                          int number_of_prefixes);
451
452         bool decode_type_with_postfix(string_type& prefix,
453             string_type& postfix, qualifier_list<Tp, Allocator>* qualifiers = NULL);
454         bool decode_bare_function_type(string_type& output);
455         bool decode_builtin_type(string_type& output);
456         bool decode_call_offset(string_type& output);
457         bool decode_class_enum_type(string_type& output);
458         bool decode_expression(string_type& output);
459         bool decode_literal(string_type& output);
460         bool decode_local_name(string_type& output);
461         bool decode_name(string_type& output,
462             string_type& nested_name_qualifiers);
463         bool decode_nested_name(string_type& output,
464             string_type& qualifiers);
465         bool decode_number(string_type& output);
466         bool decode_operator_name(string_type& output);
467         bool decode_source_name(string_type& output);
468         bool decode_substitution(string_type& output,
469             qualifier_list<Tp, Allocator>* qualifiers = NULL);
470         bool decode_template_args(string_type& output);
471         bool decode_template_param(string_type& output,
472             qualifier_list<Tp, Allocator>* qualifiers = NULL);
473         bool decode_unqualified_name(string_type& output);
474         bool decode_unscoped_name(string_type& output);
475         bool decode_non_negative_decimal_integer(string_type& output);
476         bool decode_special_name(string_type& output);
477         bool decode_real(string_type& output, size_t size_of_real);
478       };
479
480     template<typename Tp, typename Allocator>
481 #if !_GLIBCXX_DEMANGLER_CWDEBUG
482       inline
483 #endif
484       void
485       session<Tp, Allocator>::add_substitution(int start_pos,
486                                            substitution_nt sub_type,
487                                            int number_of_prefixes = 0)
488       {
489         if (!M_inside_substitution)
490         {
491 #if _GLIBCXX_DEMANGLER_CWDEBUG
492           if (M_inside_add_substitution)
493             return;
494 #endif
495           M_substitutions_pos.
496               push_back(substitution_st(start_pos,
497                   sub_type, number_of_prefixes));
498 #if _GLIBCXX_DEMANGLER_CWDEBUG
499           if (!DEBUGCHANNELS::dc::demangler.is_on())
500             return;
501           string_type substitution_name("S");
502           int n = M_substitutions_pos.size() - 1;
503           if (n > 0)
504             substitution_name += (n <= 10) ? (char)(n + '0' - 1)
505                                            : (char)(n + 'A' - 11);
506           substitution_name += '_';
507           string_type subst;
508           int saved_pos = M_pos;
509           M_pos = start_pos;
510           M_inside_add_substitution = true;
511           _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.off() );
512           switch(sub_type)
513           {
514             case type:
515               decode_type(subst);
516               break;
517             case template_template_param:
518               decode_template_param(subst);
519               break;
520             case nested_name_prefix:
521             case nested_name_template_prefix:
522               for (int cnt = number_of_prefixes; cnt > 0; --cnt)
523               {
524                 if (current() == 'I')
525                 {
526                   subst += ' ';
527                   decode_template_args(subst);
528                 }
529                 else
530                 {
531                   if (cnt < number_of_prefixes)
532                     subst += "::";
533                   if (current() == 'S')
534                     decode_substitution(subst);
535                   else if (current() == 'T')
536                     decode_template_param(subst);
537                   else
538                     decode_unqualified_name(subst);
539                 }
540               }
541               break;
542             case unscoped_template_name:
543               decode_unscoped_name(subst);
544               break;
545           }
546           M_pos = saved_pos;
547           _GLIBCXX_DEMANGLER_DEBUG( dc::demangler.on() );
548           _GLIBCXX_DEMANGLER_DOUT(dc::demangler,
549               "Adding substitution " << substitution_name
550               << " : " << subst
551               << " (from " << location_ct((char*)__builtin_return_address(0)
552                                           + builtin_return_address_offset)
553               << " <- " << location_ct((char*)__builtin_return_address(1)
554                                        + builtin_return_address_offset)
555               << " <- " << location_ct((char*)__builtin_return_address(2)
556                                        + builtin_return_address_offset)
557               << ").");
558           M_inside_add_substitution = false;
559 #endif
560         }
561       }
562
563     // We don't want to depend on locale (or include <cctype> for that matter).
564     // We also don't want to use "safe-ctype.h" because that headerfile is not
565     // available to the users.
566     inline bool isdigit(char c) { return c >= '0' && c <= '9'; }
567     inline bool islower(char c) { return c >= 'a' && c <= 'z'; }
568     inline bool isupper(char c) { return c >= 'A' && c <= 'Z'; }
569     inline char tolower(char c) { return isupper(c) ? c - 'A' + 'a' : c; }
570
571     //
572     // <non-negative decimal integer> ::= 0
573     //                                ::= 1|2|3|4|5|6|7|8|9 [<digit>+]
574     // <digit>                        ::= 0|1|2|3|4|5|6|7|8|9
575     //
576     template<typename Tp, typename Allocator>
577       bool
578       session<Tp, Allocator>::
579           decode_non_negative_decimal_integer(string_type& output)
580       {
581         char c = current();
582         if (c == '0')
583         {
584           output += '0';
585           eat_current();
586         }
587         else if (!isdigit(c))
588           M_result = false;
589         else
590         {
591           do
592           {
593             output += c;
594           }
595           while (isdigit((c = next())));
596         }
597         return M_result;
598       }
599
600     // <number> ::= [n] <non-negative decimal integer>
601     //
602     template<typename Tp, typename Allocator>
603       bool
604       session<Tp, Allocator>::decode_number(string_type& output)
605       {
606         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_number");
607         if (current() != 'n')
608           decode_non_negative_decimal_integer(output);
609         else
610         {
611           output += '-';
612           eat_current();
613           decode_non_negative_decimal_integer(output);
614         }
615         _GLIBCXX_DEMANGLER_RETURN;
616       }
617
618     // <builtin-type> ::= v  # void
619     //                ::= w  # wchar_t
620     //                ::= b  # bool
621     //                ::= c  # char
622     //                ::= a  # signed char
623     //                ::= h  # unsigned char
624     //                ::= s  # short
625     //                ::= t  # unsigned short
626     //                ::= i  # int
627     //                ::= j  # unsigned int
628     //                ::= l  # long
629     //                ::= m  # unsigned long
630     //                ::= x  # long long, __int64
631     //                ::= y  # unsigned long long, __int64
632     //                ::= n  # __int128
633     //                ::= o  # unsigned __int128
634     //                ::= f  # float
635     //                ::= d  # double
636     //                ::= e  # long double, __float80
637     //                ::= g  # __float128
638     //                ::= z  # ellipsis
639     //                ::= u <source-name>    # vendor extended type
640     //
641     char const* const builtin_type_c[26] =
642     {
643       "signed char",    // a
644       "bool",           // b
645       "char",           // c
646       "double",         // d
647       "long double",    // e
648       "float",          // f
649       "__float128",             // g
650       "unsigned char",  // h
651       "int",            // i
652       "unsigned int",   // j
653       NULL,                     // k
654       "long",           // l
655       "unsigned long",  // m
656       "__int128",               // n
657       "unsigned __int128",      // o
658       NULL,                     // p
659       NULL,                     // q
660       NULL,                     // r
661       "short",          // s
662       "unsigned short", // t
663       NULL,                     // u
664       "void",           // v
665       "wchar_t",                // w
666       "long long",              // x
667       "unsigned long long",     // y
668       "..."                     // z
669     };
670
671     //
672     template<typename Tp, typename Allocator>
673       bool
674       session<Tp, Allocator>::decode_builtin_type(string_type& output)
675       {
676         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_builtin_type");
677         char const* bt;
678         if (!islower(current()) || !(bt = builtin_type_c[current() - 'a']))
679           _GLIBCXX_DEMANGLER_FAILURE;
680         output += bt;
681         eat_current();
682         _GLIBCXX_DEMANGLER_RETURN;
683       }
684
685     // <class-enum-type> ::= <name>
686     //
687     template<typename Tp, typename Allocator>
688       bool
689       session<Tp, Allocator>::decode_class_enum_type(string_type& output)
690       {
691         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_class_enum_type");
692         string_type nested_name_qualifiers;
693         if (!decode_name(output, nested_name_qualifiers))
694           _GLIBCXX_DEMANGLER_FAILURE;
695         output += nested_name_qualifiers;
696         _GLIBCXX_DEMANGLER_RETURN;
697       }
698
699     // <substitution> ::=
700     //   S <seq-id> _
701     //   S_
702     //   St # ::std::
703     //   Sa # ::std::allocator
704     //   Sb # ::std::basic_string
705     //   Ss # ::std::basic_string<char, std::char_traits<char>,
706     //                            std::allocator<char> >
707     //   Si # ::std::basic_istream<char,  std::char_traits<char> >
708     //   So # ::std::basic_ostream<char,  std::char_traits<char> >
709     //   Sd # ::std::basic_iostream<char, std::char_traits<char> >
710     //
711     // <seq-id> ::=
712     //   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
713     //       [<seq-id>] # Base 36 number
714     //
715     template<typename Tp, typename Allocator>
716       bool
717       session<Tp, Allocator>::decode_substitution(string_type& output,
718           qualifier_list<Tp, Allocator>* qualifiers)
719       {
720         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_substitution");
721         unsigned int value = 0;
722         char c = next();
723         if (c != '_')
724         {
725           switch(c)
726           {
727             case 'a':
728             {
729               output += "std::allocator";
730               if (!M_inside_template_args)
731               {
732                 M_function_name = "allocator";
733                 M_name_is_template = true;
734                 M_name_is_cdtor = false;
735                 M_name_is_conversion_operator = false;
736               }
737               eat_current();
738               if (qualifiers)
739                 qualifiers->printing_suppressed();
740               _GLIBCXX_DEMANGLER_RETURN;
741             }
742             case 'b':
743             {
744               output += "std::basic_string";
745               if (!M_inside_template_args)
746               {
747                 M_function_name = "basic_string";
748                 M_name_is_template = true;
749                 M_name_is_cdtor = false;
750                 M_name_is_conversion_operator = false;
751               }
752               eat_current();
753               if (qualifiers)
754                 qualifiers->printing_suppressed();
755               _GLIBCXX_DEMANGLER_RETURN;
756             }
757             case 'd':
758               output += "std::iostream";
759               if (!M_inside_template_args)
760               {
761                 M_function_name = "iostream";
762                 M_name_is_template = true;
763                 M_name_is_cdtor = false;
764                 M_name_is_conversion_operator = false;
765               }
766               eat_current();
767               if (qualifiers)
768                 qualifiers->printing_suppressed();
769               _GLIBCXX_DEMANGLER_RETURN;
770             case 'i':
771               output += "std::istream";
772               if (!M_inside_template_args)
773               {
774                 M_function_name = "istream";
775                 M_name_is_template = true;
776                 M_name_is_cdtor = false;
777                 M_name_is_conversion_operator = false;
778               }
779               eat_current();
780               if (qualifiers)
781                 qualifiers->printing_suppressed();
782               _GLIBCXX_DEMANGLER_RETURN;
783             case 'o':
784               output += "std::ostream";
785               if (!M_inside_template_args)
786               {
787                 M_function_name = "ostream";
788                 M_name_is_template = true;
789                 M_name_is_cdtor = false;
790                 M_name_is_conversion_operator = false;
791               }
792               eat_current();
793               if (qualifiers)
794                 qualifiers->printing_suppressed();
795               _GLIBCXX_DEMANGLER_RETURN;
796             case 's':
797               output += "std::string";
798               if (!M_inside_template_args)
799               {
800                 M_function_name = "string";
801                 M_name_is_template = true;
802                 M_name_is_cdtor = false;
803                 M_name_is_conversion_operator = false;
804               }
805               eat_current();
806               if (qualifiers)
807                 qualifiers->printing_suppressed();
808               _GLIBCXX_DEMANGLER_RETURN;
809             case 't':
810               output += "std";
811               eat_current();
812               if (qualifiers)
813                 qualifiers->printing_suppressed();
814               _GLIBCXX_DEMANGLER_RETURN;
815             default:
816               for(;; c = next())
817               {
818                 if (isdigit(c))
819                   value = value * 36 + c - '0';
820                 else if (isupper(c))
821                   value = value * 36 + c - 'A' + 10;
822                 else if (c == '_')
823                   break;
824                 else
825                   _GLIBCXX_DEMANGLER_FAILURE;
826               }
827               ++value;
828               break;
829           }
830         }
831         eat_current();
832         if (value >= M_substitutions_pos.size() ||
833             M_inside_type > 20)                 // Rather than core dump.
834           _GLIBCXX_DEMANGLER_FAILURE;
835         ++M_inside_substitution;
836         int saved_pos = M_pos;
837         substitution_st& substitution(M_substitutions_pos[value]);
838         M_pos = substitution.M_start_pos;
839         switch(substitution.M_type)
840         {
841           case type:
842             decode_type(output, qualifiers);
843             break;
844           case template_template_param:
845             decode_template_param(output, qualifiers);
846             break;
847           case nested_name_prefix:
848           case nested_name_template_prefix:
849             for (int cnt = substitution.M_number_of_prefixes; cnt > 0; --cnt)
850             {
851               if (current() == 'I')
852               {
853                 if (M_template_args_need_space)
854                   output += ' ';
855                 M_template_args_need_space = false;
856                 if (!decode_template_args(output))
857                   _GLIBCXX_DEMANGLER_FAILURE;
858               }
859               else
860               {
861                 if (cnt < substitution.M_number_of_prefixes)
862                   output += "::";
863                 if (current() == 'S')
864                 {
865                   if (!decode_substitution(output))
866                     _GLIBCXX_DEMANGLER_FAILURE;
867                 }
868                 else if (!decode_unqualified_name(output))
869                   _GLIBCXX_DEMANGLER_FAILURE;
870               }
871             }
872             if (qualifiers)
873               qualifiers->printing_suppressed();
874             break;
875           case unscoped_template_name:
876             decode_unscoped_name(output);
877             if (qualifiers)
878               qualifiers->printing_suppressed();
879             break;
880         }
881         M_pos = saved_pos;
882         --M_inside_substitution;
883         _GLIBCXX_DEMANGLER_RETURN;
884       }
885
886     // <template-param> ::= T_                  # first template parameter
887     //                  ::= T <parameter-2 non-negative number> _
888     //
889     template<typename Tp, typename Allocator>
890       bool
891       session<Tp, Allocator>::decode_template_param(string_type& output,
892           qualifier_list<Tp, Allocator>* qualifiers)
893       {
894         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_parameter");
895         if (current() != 'T')
896           _GLIBCXX_DEMANGLER_FAILURE;
897         unsigned int value = 0;
898         char c;
899         if ((c = next()) != '_')
900         {
901           while(isdigit(c))
902           {
903             value = value * 10 + c - '0';
904             c = next();
905           }
906           ++value;
907         }
908         if (eat_current() != '_')
909           _GLIBCXX_DEMANGLER_FAILURE;
910         value += M_template_arg_pos_offset;
911         if (value >= M_template_arg_pos.size())
912           _GLIBCXX_DEMANGLER_FAILURE;
913         int saved_pos = M_pos;
914         M_pos = M_template_arg_pos[value];
915         if (M_inside_type > 20)         // Rather than core dump.
916           _GLIBCXX_DEMANGLER_FAILURE;
917         ++M_inside_substitution;
918         if (current() == 'X')
919         {
920           eat_current();
921           decode_expression(output);
922         }
923         else if (current() == 'L')
924           decode_literal(output);
925         else
926           decode_type(output, qualifiers);
927         --M_inside_substitution;
928         M_pos = saved_pos;
929         _GLIBCXX_DEMANGLER_RETURN;
930       }
931
932     template<typename Tp, typename Allocator>
933       bool
934       session<Tp, Allocator>::decode_real(string_type& output, size_t size_of_real)
935       {
936         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_real");
937
938         unsigned long words[4]; // 32 bit per long, maximum of 128 bits.
939         unsigned long* word = &words[0];
940
941         int saved_pos;
942         store(saved_pos);
943
944         // The following assumes that leading zeroes are also included in the
945         // mangled name, I am not sure that is conforming to the C++-ABI, but
946         // it is what g++ does.
947         unsigned char nibble, c = current();
948         for(size_t word_cnt = size_of_real / 4; word_cnt > 0; --word_cnt)
949         {
950           for (int nibble_cnt = 0; nibble_cnt < 8; ++nibble_cnt)
951           {
952             // Translate character into nibble.
953             if (c < '0' || c > 'f')
954               _GLIBCXX_DEMANGLER_FAILURE;
955             if (c <= '9')
956               nibble = c - '0';
957             else if (c >= 'a')
958               nibble = c - 'a' + 10;
959             else
960               _GLIBCXX_DEMANGLER_FAILURE;
961             // Write nibble into word array.
962             if (nibble_cnt == 0)
963               *word = nibble << 28;
964             else
965               *word |= (nibble << (28 - 4 * nibble_cnt));
966             c = next();
967           }
968           ++word;
969         }
970         char buf[24];
971         if (M_implementation_details.decode_real(buf, words, size_of_real))
972         {
973           output += buf;
974           _GLIBCXX_DEMANGLER_RETURN;
975         }
976         restore(saved_pos);
977
978         output += '[';
979         c = current();
980         for(size_t nibble_cnt = 0; nibble_cnt < 2 * size_of_real; ++nibble_cnt)
981         {
982           if (c < '0' || c > 'f' || (c > '9' && c < 'a'))
983             _GLIBCXX_DEMANGLER_FAILURE;
984           output += c;
985           c = next();
986         }
987         output += ']';
988
989         _GLIBCXX_DEMANGLER_RETURN;
990       }
991
992     template<typename Tp, typename Allocator>
993       bool
994       session<Tp, Allocator>::decode_literal(string_type& output)
995       {
996         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_literal");
997         eat_current();  // Eat the 'L'.
998         if (current() == '_')
999         {
1000           if (next() != 'Z')
1001             _GLIBCXX_DEMANGLER_FAILURE;
1002           eat_current();
1003           if ((M_pos += decode_encoding(output, M_str + M_pos,
1004                   M_maxpos - M_pos + 1, M_implementation_details)) < 0)
1005             _GLIBCXX_DEMANGLER_FAILURE;
1006         }
1007         else
1008         {
1009           // Special cases
1010           if (current() == 'b')
1011           {
1012             if (next() == '0')
1013               output += "false";
1014             else
1015               output += "true";
1016             eat_current();
1017             _GLIBCXX_DEMANGLER_RETURN;
1018           }
1019           char c = current();
1020           if ((c == 'i' || c == 'j' || c == 'l' ||
1021                c == 'm' || c == 'x' || c == 'y') &&
1022               M_implementation_details.get_style_literal())
1023             eat_current();
1024           else if (c == 'i' &&
1025               !M_implementation_details.get_style_literal_int())
1026             eat_current();
1027           else
1028           {
1029             output += '(';
1030             if (!decode_type(output))
1031               _GLIBCXX_DEMANGLER_FAILURE;
1032             output += ')';
1033           }
1034           if (c >= 'd' && c <= 'g')
1035           {
1036             size_t size_of_real = (c == 'd') ? sizeof(double) :
1037                 ((c == 'f') ? sizeof(float) :
1038                 (c == 'e') ?  sizeof(long double) : 16);
1039             if (!decode_real(output, size_of_real))
1040                 _GLIBCXX_DEMANGLER_FAILURE;
1041           }
1042           else if (!decode_number(output))
1043             _GLIBCXX_DEMANGLER_FAILURE;
1044           if (M_implementation_details.get_style_literal())
1045           {
1046             if (c == 'j' || c == 'm' || c == 'y')
1047               output += 'u';
1048             if (c == 'l' || c == 'm')
1049               output += 'l';
1050             if (c == 'x' || c == 'y')
1051               output += "ll";
1052           }
1053         }
1054         _GLIBCXX_DEMANGLER_RETURN;
1055       }
1056
1057     // <operator-name> ::=
1058     //   nw                             # new
1059     //   na                             # new[]
1060     //   dl                             # delete
1061     //   da                             # delete[]
1062     //   ps                             # + (unary)
1063     //   ng                             # - (unary)
1064     //   ad                             # & (unary)
1065     //   de                             # * (unary)
1066     //   co                             # ~
1067     //   pl                             # +
1068     //   mi                             # -
1069     //   ml                             # *
1070     //   dv                             # /
1071     //   rm                             # %
1072     //   an                             # &
1073     //   or                             # |
1074     //   eo                             # ^
1075     //   aS                             # =
1076     //   pL                             # +=
1077     //   mI                             # -=
1078     //   mL                             # *=
1079     //   dV                             # /=
1080     //   rM                             # %=
1081     //   aN                             # &=
1082     //   oR                             # |=
1083     //   eO                             # ^=
1084     //   ls                             # <<
1085     //   rs                             # >>
1086     //   lS                             # <<=
1087     //   rS                             # >>=
1088     //   eq                             # ==
1089     //   ne                             # !=
1090     //   lt                             # <
1091     //   gt                             # >
1092     //   le                             # <=
1093     //   ge                             # >=
1094     //   nt                             # !
1095     //   aa                             # &&
1096     //   oo                             # ||
1097     //   pp                             # ++
1098     //   mm                             # --
1099     //   cm                             # ,
1100     //   pm                             # ->*
1101     //   pt                             # ->
1102     //   cl                             # ()
1103     //   ix                             # []
1104     //   qu                             # ?
1105     //   st                             # sizeof (a type)
1106     //   sz                             # sizeof (an expression)
1107     //   cv <type>                      # (cast)
1108     //   v <digit> <source-name>        # vendor extended operator
1109     //
1110     // Symbol operator codes exist of two characters, we need to find a
1111     // quick hash so that their names can be looked up in a table.
1112     //
1113     // The puzzle :)
1114     // Shift the rows so that there is at most one character per column.
1115     //
1116     // A perfect solution (Oh no, it's THE MATRIX!):
1117     //                                              horizontal
1118     //    .......................................   offset + 'a'
1119     // a, a||d|||||||||n||||s||||||||||||||||||||       0
1120     // c,  || |||||||lm o||| ||||||||||||||||||||       0
1121     // d,  || a|||e||    l|| ||||||v|||||||||||||       4
1122     // e,  ||  ||| ||     || |||o|q |||||||||||||       8
1123     // g,  ||  ||| ||     || e|| |  ||||||||t||||      15
1124     // i,  ||  ||| ||     ||  || |  |||||||| |||x      15
1125     // l,  |e  ||| ||     st  || |  |||||||| |||       -2
1126     // m,  |   |i| lm         || |  |||||||| |||       -2
1127     // n,  a   e g            t| w  |||||||| |||        1
1128     // o,                      |    ||||o||r |||       16
1129     // p,                      |    ||lm |p  st|       17
1130     // q,                      |    u|   |     |        6
1131     // r,                      m     s   |     |        9
1132     // s,                                t     z       12
1133     //    .......................................
1134     // ^            ^__ second character
1135     // |___ first character
1136     //
1137
1138     // Putting that solution in tables:
1139
1140     char const offset_table_c [1 + CHAR_MAX - CHAR_MIN ] =
1141     {
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       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1145       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
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 #if (CHAR_MIN < 0)
1149       // Add -CHAR_MIN extra zeroes (128):
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       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1155       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1156       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1157       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
1158       //   a    b    c    d    e    f    g    h    i    j    k
1159       0, -97,   0, -97, -93, -89,   0, -82,   0, -82,   0,   0,
1160       //   l    m    n    o    p    q    r    s    t    u    v
1161          -99, -99, -96, -81, -80, -91, -88, -85,   0,   0,   0,
1162 #else
1163       //   a    b    c    d    e    f    g    h    i    j    k
1164       0, 159,   0, 159, 163, 167,   0, 174,   0, 174,   0,   0,
1165       //   l    m    n    o    p    q    r    s    t    u    v
1166          157, 157, 160, 175, 176, 165, 168, 171,   0,   0,   0,
1167 #endif
1168       // ... more zeros
1169     };
1170
1171     enum xary_nt {
1172       unary,
1173       binary,
1174       trinary
1175     };
1176
1177     struct entry_st
1178     {
1179       char const* opcode;
1180       char const* symbol_name;
1181       xary_nt type;
1182     };
1183
1184     entry_st const symbol_name_table_c[39] = {
1185       { "aa",  "operator&&", binary },
1186       { "na",  "operator new[]", unary },
1187       { "le",  "operator<=", binary },
1188       { "ad",  "operator&", unary },
1189       { "da",  "operator delete[]", unary },
1190       { "ne",  "operator!=", binary },
1191       { "mi=", "operator-", binary },
1192       { "ng",  "operator-", unary },
1193       { "de",  "operator*", unary },
1194       { "ml=", "operator*", binary },
1195       { "mm",  "operator--", unary },
1196       { "cl",  "operator()", unary },
1197       { "cm",  "operator,", binary },
1198       { "an=", "operator&", binary },
1199       { "co",  "operator~", binary },
1200       { "dl",  "operator delete", unary },
1201       { "ls=", "operator<<", binary },
1202       { "lt",  "operator<", binary },
1203       { "as=", "operator", binary },
1204       { "ge",  "operator>=", binary },
1205       { "nt",  "operator!", unary },
1206       { "rm=", "operator%", binary },
1207       { "eo=", "operator^", binary },
1208       { "nw",  "operator new", unary },
1209       { "eq",  "operator==", binary },
1210       { "dv=", "operator/", binary },
1211       { "qu",  "operator?", trinary },
1212       { "rs=", "operator>>", binary },
1213       { "pl=", "operator+", binary },
1214       { "pm",  "operator->*", binary },
1215       { "oo",  "operator||", binary },
1216       { "st",  "sizeof", unary },
1217       { "pp",  "operator++", unary },
1218       { "or=", "operator|", binary },
1219       { "gt",  "operator>", binary },
1220       { "ps",  "operator+", unary },
1221       { "pt",  "operator->", binary },
1222       { "sz",  "sizeof", unary },
1223       { "ix",  "operator[]", unary }
1224     };
1225
1226     template<typename Tp, typename Allocator>
1227       bool
1228       session<Tp, Allocator>::decode_operator_name(string_type& output)
1229       {
1230         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_operator_name");
1231
1232         char opcode0 = current();
1233         char opcode1 = tolower(next());
1234
1235         register char hash;
1236         if ((hash = offset_table_c[opcode0 - CHAR_MIN]))
1237         {
1238           hash += opcode1;
1239           if (
1240 #if (CHAR_MIN < 0)
1241               hash >= 0 &&
1242 #endif
1243               hash < 39)
1244           {
1245             int index = static_cast<int>(static_cast<unsigned char>(hash));
1246             entry_st entry = symbol_name_table_c[index];
1247             if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1248                 && (opcode1 == current() || entry.opcode[2] == '='))
1249             {
1250               output += entry.symbol_name;
1251               if (opcode1 != current())
1252                 output += '=';
1253               eat_current();
1254               if (hash == 16 || hash == 17)
1255                 M_template_args_need_space = true;
1256               _GLIBCXX_DEMANGLER_RETURN;
1257             }
1258             else if (opcode0 == 'c' && opcode1 == 'v')  // casting operator
1259             {
1260               eat_current();
1261               output += "operator ";
1262               if (current() == 'T')
1263               {
1264                 // This is a templated cast operator.
1265                 // It must be of the form "cvT_I...E".
1266                 // Let M_template_arg_pos already point
1267                 // to the template argument.
1268                 M_template_arg_pos_offset = M_template_arg_pos.size();
1269                 M_template_arg_pos.push_back(M_pos + 3);
1270               }
1271               if (!decode_type(output))
1272                 _GLIBCXX_DEMANGLER_FAILURE;
1273               if (!M_inside_template_args)
1274                 M_name_is_conversion_operator = true;
1275               _GLIBCXX_DEMANGLER_RETURN;
1276             }
1277           }
1278         }
1279         _GLIBCXX_DEMANGLER_FAILURE;
1280       }
1281
1282     //
1283     // <expression> ::= <unary operator-name> <expression>
1284     //              ::= <binary operator-name> <expression> <expression>
1285     //              ::= <trinary operator-name> <expression> <expression> <expression>
1286     //              ::= st <type>
1287     //              ::= <template-param>
1288     //              ::= sr <type> <unqualified-name>                   # dependent name
1289     //              ::= sr <type> <unqualified-name> <template-args>   # dependent template-id
1290     //              ::= <expr-primary>
1291     //
1292     // <expr-primary> ::= L <type> <value number> E     # integer literal
1293     //                ::= L <type> <value float> E      # floating literal
1294     //                ::= L <mangled-name> E            # external name
1295     //
1296     template<typename Tp, typename Allocator>
1297       bool
1298       session<Tp, Allocator>::decode_expression(string_type& output)
1299       {
1300         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_expression");
1301         if (current() == 'T')
1302         {
1303           if (!decode_template_param(output))
1304             _GLIBCXX_DEMANGLER_FAILURE;
1305           _GLIBCXX_DEMANGLER_RETURN;
1306         }
1307         else if (current() == 'L')
1308         {
1309           if (!decode_literal(output))
1310             _GLIBCXX_DEMANGLER_FAILURE;
1311           if (current() != 'E')
1312             _GLIBCXX_DEMANGLER_FAILURE;
1313           eat_current();
1314           _GLIBCXX_DEMANGLER_RETURN;
1315         }
1316         else if (current() == 's')
1317         {
1318           char opcode1 = next();
1319           if (opcode1 == 't' || opcode1 == 'z')
1320           {
1321             eat_current();
1322             if (M_implementation_details.get_style_compact_expr_ops())
1323               output += "sizeof(";
1324             else
1325               output += "sizeof (";
1326             if (opcode1 == 't')
1327             {
1328               // I cannot think of a mangled name that is valid for both cases
1329               // when just replacing the 't' by a 'z' or vica versa, which
1330               // indicates that there is no ambiguity that dictates the need
1331               // for a seperate "st" case, except to be able catch invalid
1332               // mangled names.  However there CAN be ambiguity in the demangled
1333               // name when there are both a type and a symbol of the same name,
1334               // which then leads to different encoding (of course) with
1335               // sizeof (type) or sizeof (expression) respectively, but that
1336               // ambiguity is not per se related to "sizeof" except that that
1337               // is the only place where both a type AND an expression are valid
1338               // in as part of a (template function) type.
1339               //
1340               // Example:
1341               //
1342               // struct B { typedef int t; };
1343               // struct A : public B { static int t[2]; };
1344               // template<int i, int j> struct C { typedef int q; };
1345               // template<int i, typename T>
1346               //   void f(typename C<sizeof (typename T::t),
1347               //                     sizeof (T::t)>::q) { }
1348               // void instantiate() { f<5, A>(0); }
1349               //
1350               // Leads to _Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE which
1351               // demangles as
1352               // void f<5, A>(C<sizeof (T::t), sizeof (T::t)>::q)
1353               //
1354               // This is ambiguity is very unlikely to happen and it is kind
1355               // of fuzzy to detect when adding a 'typename' makes sense.
1356               //
1357               if (M_implementation_details.get_style_sizeof_typename())
1358               {
1359                 // We can only get here inside a template parameter,
1360                 // so this is syntactically correct if the given type is
1361                 // a typedef.  The only disadvantage is that it is inconsistent
1362                 // with all other places where the 'typename' keyword should be
1363                 // used and we don't.
1364                 // With this, the above example will demangle as
1365                 // void f<5, A>(C<sizeof (typename T::t), sizeof (T::t)>::q)
1366                 if (current() == 'N' || // <nested-name>
1367                                           // This should be a safe bet.
1368                     (current() == 'S' &&
1369                      next_peek() == 't'))       // std::something, guess that
1370                                           // this involves a typedef.
1371                   output += "typename ";
1372               }
1373               if (!decode_type(output))
1374                 _GLIBCXX_DEMANGLER_FAILURE;
1375             }
1376             else
1377             {
1378               if (!decode_expression(output))
1379                 _GLIBCXX_DEMANGLER_FAILURE;
1380             }
1381             output += ')';
1382             _GLIBCXX_DEMANGLER_RETURN;
1383           }
1384           else if (current() == 'r')
1385           {
1386             eat_current();
1387             if (!decode_type(output))
1388               _GLIBCXX_DEMANGLER_FAILURE;
1389             output += "::";
1390             if (!decode_unqualified_name(output))
1391               _GLIBCXX_DEMANGLER_FAILURE;
1392             if (current() != 'I' || decode_template_args(output))
1393               _GLIBCXX_DEMANGLER_RETURN;
1394           }
1395         }
1396         else
1397         {
1398           char opcode0 = current();
1399           char opcode1 = tolower(next());
1400
1401           register char hash;
1402           if ((hash = offset_table_c[opcode0 - CHAR_MIN]))
1403           {
1404             hash += opcode1;
1405             if (
1406 #if (CHAR_MIN < 0)
1407                 hash >= 0 &&
1408 #endif
1409                 hash < 39)
1410             {
1411               int index = static_cast<int>(static_cast<unsigned char>(hash));
1412               entry_st entry = symbol_name_table_c[index];
1413               if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1414                   && (opcode1 == current() || entry.opcode[2] == '='))
1415               {
1416                 char const* op = entry.symbol_name + 8; // Skip "operator".
1417                 if (*op == ' ')                         // operator new and delete.
1418                   ++op;
1419                 if (entry.type == unary)
1420                   output += op;
1421                 bool is_eq = (opcode1 != current());
1422                 eat_current();
1423                 if (index == 34 && M_inside_template_args)      // operator>
1424                   output += '(';
1425                 output += '(';
1426                 if (!decode_expression(output))
1427                   _GLIBCXX_DEMANGLER_FAILURE;
1428                 output += ')';
1429                 if (entry.type != unary)
1430                 {
1431                   if (!M_implementation_details.get_style_compact_expr_ops())
1432                     output += ' ';
1433                   output += op;
1434                   if (is_eq)
1435                     output += '=';
1436                   if (!M_implementation_details.get_style_compact_expr_ops())
1437                     output += ' ';
1438                   output += '(';
1439                   if (!decode_expression(output))
1440                     _GLIBCXX_DEMANGLER_FAILURE;
1441                   output += ')';
1442                   if (index == 34 && M_inside_template_args)
1443                     output += ')';
1444                   if (entry.type == trinary)
1445                   {
1446                     if (M_implementation_details.get_style_compact_expr_ops())
1447                       output += ":(";
1448                     else
1449                       output += " : (";
1450                     if (!decode_expression(output))
1451                       _GLIBCXX_DEMANGLER_FAILURE;
1452                     output += ')';
1453                   }
1454                 }
1455                 _GLIBCXX_DEMANGLER_RETURN;
1456               }
1457               else if (opcode0 == 'c' &&
1458                        opcode1 == 'v')          // casting operator.
1459               {
1460                 eat_current();
1461                 output += '(';
1462                 if (!decode_type(output))
1463                   _GLIBCXX_DEMANGLER_FAILURE;
1464                 output += ")(";
1465                 if (!decode_expression(output))
1466                   _GLIBCXX_DEMANGLER_FAILURE;
1467                 output += ')';
1468                 _GLIBCXX_DEMANGLER_RETURN;
1469               }
1470             }
1471           }
1472         }
1473         _GLIBCXX_DEMANGLER_FAILURE;
1474       }
1475
1476     //
1477     // <template-args> ::= I <template-arg>+ E
1478     // <template-arg> ::= <type>                        # type or template
1479     //                ::= L <type> <value number> E     # integer literal
1480     //                ::= L <type> <value float> E      # floating literal
1481     //                ::= L <mangled-name> E            # external name
1482     //                ::= X <expression> E              # expression
1483     template<typename Tp, typename Allocator>
1484       bool
1485       session<Tp, Allocator>::decode_template_args(string_type& output)
1486       {
1487         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_args");
1488         if (eat_current() != 'I')
1489           _GLIBCXX_DEMANGLER_FAILURE;
1490         int prev_size = M_template_arg_pos.size();
1491         ++M_inside_template_args;
1492         if (M_template_args_need_space)
1493         {
1494           output += ' ';
1495           M_template_args_need_space = false;
1496         }
1497         output += '<';
1498         for(;;)
1499         {
1500           if (M_inside_template_args == 1 && !M_inside_type)
1501             M_template_arg_pos.push_back(M_pos);
1502           if (current() == 'X')
1503           {
1504             eat_current();
1505             if (!decode_expression(output))
1506               _GLIBCXX_DEMANGLER_FAILURE;
1507             if (current() != 'E')
1508               _GLIBCXX_DEMANGLER_FAILURE;
1509             eat_current();
1510           }
1511           else if (current() == 'L')
1512           {
1513             if (!decode_literal(output))
1514               _GLIBCXX_DEMANGLER_FAILURE;
1515             if (current() != 'E')
1516               _GLIBCXX_DEMANGLER_FAILURE;
1517             eat_current();
1518           }
1519           else if (!decode_type(output))
1520             _GLIBCXX_DEMANGLER_FAILURE;
1521           if (current() == 'E')
1522             break;
1523           output += ", ";
1524         }
1525         eat_current();
1526         if (*(output.rbegin()) == '>')
1527           output += ' ';
1528         output += '>';
1529         --M_inside_template_args;
1530         if (!M_inside_template_args && !M_inside_type)
1531         {
1532           M_name_is_template = true;
1533           M_template_arg_pos_offset = prev_size;
1534         }
1535         _GLIBCXX_DEMANGLER_RETURN;
1536       }
1537
1538     // <bare-function-type> ::=
1539     //   <signature type>+              # Types are parameter types.
1540     //
1541     // Note that the possible return type of the <bare-function-type>
1542     // has already been eaten before we call this function.  This makes
1543     // our <bare-function-type> slightly different from the one in
1544     // the C++-ABI description.
1545     //
1546     template<typename Tp, typename Allocator>
1547       bool
1548       session<Tp, Allocator>::decode_bare_function_type(string_type& output)
1549       {
1550         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_bare_function_type");
1551         if (M_saw_destructor)
1552         {
1553           if (eat_current() != 'v' || (current() != 'E' && current() != 0))
1554             _GLIBCXX_DEMANGLER_FAILURE;
1555           output += "()";
1556           M_saw_destructor = false;
1557           _GLIBCXX_DEMANGLER_RETURN;
1558         }
1559         if (current() == 'v' && !M_implementation_details.get_style_void())
1560         {
1561           eat_current();
1562           if (current() != 'E' && current() != 0)
1563             _GLIBCXX_DEMANGLER_FAILURE;
1564           output += "()";
1565           M_saw_destructor = false;
1566           _GLIBCXX_DEMANGLER_RETURN;
1567         }
1568         output += '(';
1569         M_template_args_need_space = false;
1570         if (!decode_type(output))       // Must have at least one parameter.
1571           _GLIBCXX_DEMANGLER_FAILURE;
1572         while (current() != 'E' && current() != 0)
1573         {
1574           output += ", ";
1575           if (!decode_type(output))
1576             _GLIBCXX_DEMANGLER_FAILURE;
1577         }
1578         output += ')';
1579         _GLIBCXX_DEMANGLER_RETURN;
1580       }
1581
1582     // <type> ::=
1583     //   <builtin-type>         # Starts with a lower case character != r.
1584     //   <function-type>        # Starts with F
1585     //   <class-enum-type>      # Starts with N, S, C, D, Z, a digit or a lower
1586     //                          # case character.  Since a lower case character
1587     //                          # would be an operator name, that would be an
1588     //                          # error.  The S is a substitution or St
1589     //                          # (::std::).  A 'C' would be a constructor and
1590     //                          # thus also an error.
1591     //   <template-param>       # Starts with T
1592     //   <substitution>         # Starts with S
1593     //   <template-template-param> <template-args>  # Starts with T or S,
1594     //                                              # equivalent with the above.
1595     //
1596     //   <array-type>                   # Starts with A
1597     //   <pointer-to-member-type>       # Starts with M
1598     //   <CV-qualifiers> <type>         # Starts with r, V or K
1599     //   P <type>   # pointer-to        # Starts with P
1600     //   R <type>   # reference-to      # Starts with R
1601     //   C <type>   # complex (C 2000)  # Starts with C
1602     //   G <type>   # imaginary (C 2000)# Starts with G
1603     //   U <source-name> <type>         # vendor extended type qualifier,
1604     //                                  # starts with U
1605     //
1606     // <template-template-param> ::= <template-param>
1607     //                           ::= <substitution>
1608
1609     // My own analysis of how to decode qualifiers:
1610     //
1611     // F is a <function-type>, <T> is a <builtin-type>, <class-enum-type>,
1612     //   <template-param> or <template-template-param> <template-args>.
1613     // <Q> represents a series of qualifiers (not G or C).
1614     // <C> is an unqualified type.
1615     // <R> is a qualified type.
1616     // <B> is the bare-function-type without return type.
1617     // <I> is the array index.
1618     //                                          Substitutions:
1619     // <Q>M<C><Q2>F<R><B>E  ==> R (C::*Q)B Q2   "<C>", "F<R><B>E"
1620     //                                              (<R> and <B> recursive),
1621     //                                              "M<C><Q2>F<R><B>E".
1622     // <Q>F<R><B>E          ==> R (Q)B          "<R>", "<B>" (<B> recursive)
1623     //                                              and "F<R><B>E".
1624     //
1625     // Note that if <R> has postfix qualifiers (an array or function), then
1626     // those are added AFTER the (member) function type.  For example:
1627     // <Q>FPA<R><B>E ==> R (*(Q)B) [], where the PA added the prefix
1628     // "(*" and the postfix ") []".
1629     //
1630     // <Q>G<T>              ==> imaginary T Q   "<T>", "G<T>" (<T> recursive).
1631     // <Q>C<T>              ==> complex T Q     "<T>", "C<T>" (<T> recursive).
1632     // <Q><T>               ==> T Q             "<T>" (<T> recursive).
1633     //
1634     // where <Q> is any of:
1635     //
1636     // <Q>P             ==> *Q                          "P..."
1637     // <Q>R             ==> &Q                          "R..."
1638     // <Q>[K|V|r]+      ==> [ const| volatile| restrict]+Q      "KVr..."
1639     // <Q>U<S>          ==>  SQ                         "U<S>..."
1640     // <Q>M<C>          ==> C::*Q                       "M<C>..." (<C> recurs.)
1641     // A<I>             ==>  [I]                        "A<I>..." (<I> recurs.)
1642     // <Q>A<I>          ==>  (Q) [I]                    "A<I>..." (<I> recurs.)
1643     //   Note that when <Q> ends on an A<I2> then the brackets are omitted
1644     //   and no space is written between the two:
1645     //   A<I2>A<I>      ==>  [I2][I]
1646     //   If <Q> ends on [KVr]+, which can happen in combination with
1647     //   substitutions only, then special handling is required, see below.
1648     //
1649     // A <substitution> is handled with an input position switch during which
1650     // new substitutions are turned off.  Because recursive handling of types
1651     // (and therefore the order in which substitutions must be generated) must
1652     // be done left to right, but the generation of Q needs processing right to
1653     // left, substitutions per <type> are generated by reading the input left
1654     // to right and marking the starts of all substitutions only - implicitly
1655     // finishing them at the end of the type.  Then the output and real
1656     // substitutions are generated.
1657     //
1658     // The following comment was for the demangling of g++ version 3.0.x.  The
1659     // mangling (and I believe even the ABI description) have been fixed now
1660     // (as of g++ version 3.1).
1661     //
1662     // g++ 3.0.x only:
1663     // The ABI specifies for pointer-to-member function types the format
1664     // <Q>M<T>F<R><B>E.  In other words, the qualifier <Q2> (see above) is
1665     // implicitely contained in <T> instead of explicitly part of the M format.
1666     // I am convinced that this is a bug in the ABI.  Unfortunately, this is
1667     // how we have to demangle things as it has a direct impact on the order
1668     // in which substitutions are stored.  This ill-formed design results in
1669     // rather ill-formed demangler code too however :/
1670     //
1671     // <Q2> is now explicitely part of the M format.
1672     // For some weird reason, g++ (3.2.1) does not add substitutions for
1673     // qualified member function pointers.  I think that is another bug.
1674     //
1675
1676     // In the case of
1677     // <Q>A<I>
1678     // where <Q> ends on [K|V|r]+ then that part should be processed as
1679     // if it was behind the A<I> instead of in front of it.  This is
1680     // because a constant array of ints is normally always mangled as
1681     // an array of constant ints.  KVr qualifiers can end up in front
1682     // of an array when the array is part of a substitution or template
1683     // parameter, but the demangling should still result in the same
1684     // syntax; thus KA2_i (const array of ints) must result in the same
1685     // demangling as A2_Ki (array of const ints).  As a result we must
1686     // demangle ...[...[[KVr]+A<I0>][KVr]+A<I1>]...[KVr]+A<In>[KVr]+
1687     // as A<I0>A<I1>...A<In>[KVr]+ where each K, V and r in the series
1688     // collapses to a single character at the right of the string.
1689     // For example:
1690     // VA9_KrA6_KVi --> A9_A6_KVri --> int volatile const restrict [9][6]
1691     // Note that substitutions are still added as usual (the translation
1692     // to A9_A6_KVri does not really happen).
1693     //
1694     // This decoding is achieved by delaying the decoding of any sequence
1695     // of [KVrA]'s and processing them together in the order: first the
1696     // short-circuited KVr part and then the arrays.
1697     static int const cvq_K = 1;         // Saw at least one K
1698     static int const cvq_V = 2;         // Saw at least one V
1699     static int const cvq_r = 4;         // Saw at least one r
1700     static int const cvq_A = 8;         // Saw at least one A
1701     static int const cvq_last = 16;     // No remaining qualifiers.
1702     static int const cvq_A_cnt = 32;    // Bit 5 and higher represent the
1703                                         //   number of A's in the series.
1704     // In the function below, iter_array points to the first (right most)
1705     // A in the series, if any.
1706     template<typename Tp, typename Allocator>
1707       void
1708       qualifier_list<Tp, Allocator>::decode_KVrA(
1709           string_type& prefix, string_type& postfix, int cvq,
1710           typename qual_vector::const_reverse_iterator const& iter_array) const
1711         {
1712           _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA");
1713           if ((cvq & cvq_K))
1714             prefix += " const";
1715           if ((cvq & cvq_V))
1716             prefix += " volatile";
1717           if ((cvq & cvq_r))
1718             prefix += " restrict";
1719           if ((cvq & cvq_A))
1720           {
1721             int n = cvq >> 5;
1722             for (typename qual_vector::
1723                 const_reverse_iterator iter = iter_array;
1724                 iter != M_qualifier_starts.rend(); ++iter)
1725             {
1726               switch((*iter).first_qualifier())
1727               {
1728                 case 'K':
1729                 case 'V':
1730                 case 'r':
1731                   break;
1732                 case 'A':
1733                 {
1734                   string_type index = (*iter).get_optional_type();
1735                   if (--n == 0 && (cvq & cvq_last))
1736                     postfix = " [" + index + "]" + postfix;
1737                   else if (n > 0)
1738                     postfix = "[" + index + "]" + postfix;
1739                   else
1740                   {
1741                     prefix += " (";
1742                     postfix = ") [" + index + "]" + postfix;
1743                   }
1744                   break;
1745                 }
1746                 default:
1747                   _GLIBCXX_DEMANGLER_RETURN3;
1748               }
1749             }
1750           }
1751           _GLIBCXX_DEMANGLER_RETURN3;
1752         }
1753
1754     template<typename Tp, typename Allocator>
1755       void
1756       qualifier_list<Tp, Allocator>::decode_qualifiers(
1757           string_type& prefix,
1758           string_type& postfix,
1759           bool member_function_pointer_qualifiers = false) const
1760       {
1761         _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers");
1762         int cvq = 0;
1763         typename qual_vector::const_reverse_iterator iter_array;
1764         for(typename qual_vector::
1765             const_reverse_iterator iter = M_qualifier_starts.rbegin();
1766             iter != M_qualifier_starts.rend(); ++iter)
1767         {
1768           if (!member_function_pointer_qualifiers
1769               && !(*iter).part_of_substitution())
1770           {
1771             int saved_inside_substitution = M_demangler.M_inside_substitution;
1772             M_demangler.M_inside_substitution = 0;
1773             M_demangler.add_substitution((*iter).get_start_pos(), type);
1774             M_demangler.M_inside_substitution = saved_inside_substitution;
1775           }
1776           char qualifier_char = (*iter).first_qualifier();
1777           for(; qualifier_char; qualifier_char = (*iter).next_qualifier())
1778           {
1779             switch(qualifier_char)
1780             {
1781               case 'P':
1782                 if (cvq)
1783                 {
1784                   decode_KVrA(prefix, postfix, cvq, iter_array);
1785                   cvq = 0;
1786                 }
1787                 prefix += "*";
1788                 break;
1789               case 'R':
1790                 if (cvq)
1791                 {
1792                   decode_KVrA(prefix, postfix, cvq, iter_array);
1793                   cvq = 0;
1794                 }
1795                 prefix += "&";
1796                 break;
1797               case 'K':
1798                 cvq |= cvq_K;
1799                 continue;
1800               case 'V':
1801                 cvq |= cvq_V;
1802                 continue;
1803               case 'r':
1804                 cvq |= cvq_r;
1805                 continue;
1806               case 'A':
1807                 if (!(cvq & cvq_A))
1808                 {
1809                   cvq |= cvq_A;
1810                   iter_array = iter;
1811                 }
1812                 cvq += cvq_A_cnt;
1813                 break;
1814               case 'M':
1815                 if (cvq)
1816                 {
1817                   decode_KVrA(prefix, postfix, cvq, iter_array);
1818                   cvq = 0;
1819                 }
1820                 prefix += " ";
1821                 prefix += (*iter).get_optional_type();
1822                 prefix += "::*";
1823                 break;
1824               case 'U':
1825                 if (cvq)
1826                 {
1827                   decode_KVrA(prefix, postfix, cvq, iter_array);
1828                   cvq = 0;
1829                 }
1830                 prefix += " ";
1831                 prefix += (*iter).get_optional_type();
1832                 break;
1833               case 'G': // Only here so we added a substitution.
1834                 break;
1835             }
1836             break;
1837           }
1838         }
1839         if (cvq)
1840           decode_KVrA(prefix, postfix, cvq|cvq_last, iter_array);
1841         M_printing_suppressed = false;
1842         _GLIBCXX_DEMANGLER_RETURN3;
1843       }
1844
1845     //
1846     template<typename Tp, typename Allocator>
1847       bool
1848       session<Tp, Allocator>::decode_type_with_postfix(
1849           string_type& prefix, string_type& postfix,
1850           qualifier_list<Tp, Allocator>* qualifiers)
1851       {
1852         _GLIBCXX_DEMANGLER_DOUT_ENTERING2("decode_type");
1853         ++M_inside_type;
1854         bool recursive_template_param_or_substitution_call;
1855         if (!(recursive_template_param_or_substitution_call = qualifiers))
1856         {
1857           qualifier_list<Allocator>* raw_qualifiers = M_qualifier_list_alloc.allocate(1);
1858           qualifiers = new (raw_qualifiers) qualifier_list<Allocator>(*this);
1859         }
1860         // First eat all qualifiers.
1861         bool failure = false;
1862         for(;;)         // So we can use 'continue' to eat the next qualifier.
1863         {
1864           int start_pos = M_pos;
1865           switch(current())
1866           {
1867             case 'P':
1868               qualifiers->add_qualifier_start(pointer, start_pos,
1869                   M_inside_substitution);
1870               eat_current();
1871               continue;
1872             case 'R':
1873               qualifiers->add_qualifier_start(reference, start_pos,
1874                   M_inside_substitution);
1875               eat_current();
1876               continue;
1877             case 'K':
1878             case 'V':
1879             case 'r':
1880             {
1881               char c;
1882               int count = 0;
1883               do
1884               {
1885                 ++count;
1886                 c = next();
1887               }
1888               while(c == 'K' || c == 'V' || c == 'r');
1889               qualifiers->add_qualifier_start(cv_qualifier, start_pos, count,
1890                   M_inside_substitution);
1891               continue;
1892             }
1893             case 'U':
1894             {
1895               eat_current();
1896               string_type source_name;
1897               if (!decode_source_name(source_name))
1898               {
1899                 failure = true;
1900                 break;
1901               }
1902               qualifiers->add_qualifier_start(vendor_extension, start_pos,
1903                   source_name, M_inside_substitution);
1904               continue;
1905             }
1906             case 'A':
1907             {
1908               // <array-type> ::= A <positive dimension number> _ <element type>
1909               //              ::= A [<dimension expression>] _ <element type>
1910               //
1911               string_type index;
1912               int saved_pos;
1913               store(saved_pos);
1914               if (next() == 'n' || !decode_number(index))
1915               {
1916                 restore(saved_pos);
1917                 if (next() != '_' && !decode_expression(index))
1918                 {
1919                   failure = true;
1920                   break;
1921                 }
1922               }
1923               if (eat_current() != '_')
1924               {
1925                 failure = true;
1926                 break;
1927               }
1928               qualifiers->add_qualifier_start(array, start_pos, index,
1929                   M_inside_substitution);
1930               continue;
1931             }
1932             case 'M':
1933             {
1934               // <pointer-to-member-type> ::= M <class type> <member type>
1935               // <Q>M<C> or <Q>M<C><Q2>F<R><B>E
1936               eat_current();
1937               string_type class_type;
1938               if (!decode_type(class_type))             // Substitution: "<C>".
1939               {
1940                 failure = true;
1941                 break;
1942               }
1943               char c = current();
1944               if (c == 'F' || c == 'K' || c == 'V' || c == 'r')
1945                   // Must be CV-qualifiers and a member function pointer.
1946               {
1947                 // <Q>M<C><Q2>F<R><B>E  ==> R (C::*Q)B Q2
1948                 //     substitutions: "<C>", "F<R><B>E" (<R> and <B>
1949                 //                    recursive), "M<C><Q2>F<R><B>E".
1950                 int count = 0;
1951                 int Q2_start_pos = M_pos;
1952                 while(c == 'K' || c == 'V' || c == 'r')         // Decode <Q2>.
1953                 {
1954                   ++count;
1955                   c = next();
1956                 }
1957                 qualifier_list<Tp, Allocator> class_type_qualifiers(*this);
1958                 if (count)
1959                   class_type_qualifiers.
1960                       add_qualifier_start(cv_qualifier, Q2_start_pos,
1961                           count, M_inside_substitution);
1962                 string_type member_function_qualifiers;
1963                 // It is unclear why g++ doesn't add a substitution for
1964                 // "<Q2>F<R><B>E" as it should I think.
1965                 string_type member_function_qualifiers_postfix;
1966                 class_type_qualifiers.
1967                     decode_qualifiers(member_function_qualifiers,
1968                         member_function_qualifiers_postfix, true);
1969                 member_function_qualifiers +=
1970                     member_function_qualifiers_postfix;
1971                 // I don't think this substitution is actually ever used.
1972                 int function_pos = M_pos;
1973                 if (eat_current() != 'F')
1974                 {
1975                   failure = true;
1976                   break;
1977                 }
1978                 // Return type.
1979                 // Constructors, destructors and conversion operators don't
1980                 // have a return type, but seem to never get here.
1981                 string_type return_type_postfix;
1982                 if (!decode_type_with_postfix(prefix, return_type_postfix))
1983                     // substitution: <R> recursive
1984                 {
1985                   failure = true;
1986                   break;
1987                 }
1988                 prefix += " (";
1989                 prefix += class_type;
1990                 prefix += "::*";
1991                 string_type bare_function_type;
1992                 if (!decode_bare_function_type(bare_function_type)
1993                     || eat_current() != 'E')    // Substitution: <B> recursive.
1994                 {
1995                   failure = true;
1996                   break;
1997                 }
1998                 // substitution: "F<R><B>E".
1999                 add_substitution(function_pos, type);
2000                 // substitution: "M<C><Q2>F<R><B>E".
2001                 add_substitution(start_pos, type);
2002                 // substitution: all qualified types if any.
2003                 qualifiers->decode_qualifiers(prefix, postfix);
2004                 postfix += ")";
2005                 postfix += bare_function_type;
2006                 postfix += member_function_qualifiers;
2007                 postfix += return_type_postfix;
2008                 goto decode_type_exit;
2009               }
2010               qualifiers->add_qualifier_start(pointer_to_member, start_pos,
2011                   class_type, M_inside_substitution);
2012               continue;
2013             }
2014             default:
2015               break;
2016           }
2017           break;
2018         }
2019         if (!failure)
2020         {
2021           // <Q>G<T>                    ==> imaginary T Q
2022           //     substitutions: "<T>", "G<T>" (<T> recursive).
2023           // <Q>C<T>                    ==> complex T Q
2024           //     substitutions: "<T>", "C<T>" (<T> recursive).
2025           if (current() == 'C' || current() == 'G')
2026           {
2027             prefix += current() == 'C' ? "complex " : "imaginary ";
2028             qualifiers->add_qualifier_start(complex_or_imaginary, M_pos,
2029                 M_inside_substitution);
2030             eat_current();
2031           }
2032           int start_pos = M_pos;
2033           switch(current())
2034           {
2035             case 'F':
2036             {
2037               // <function-type> ::= F [Y] <bare-function-type> E
2038               //
2039               // Note that g++ never generates the 'Y', but we try to
2040               // demangle it anyway.
2041               bool extern_C = (next() == 'Y');
2042               if (extern_C)
2043                 eat_current();
2044
2045               // <Q>F<R><B>E            ==> R (Q)B
2046               //     substitution: "<R>", "<B>" (<B> recursive) and "F<R><B>E".
2047
2048               // Return type.
2049               string_type return_type_postfix;
2050               if (!decode_type_with_postfix(prefix, return_type_postfix))
2051                   // Substitution: "<R>".
2052               {
2053                 failure = true;
2054                 break;
2055               }
2056               // Only array and function (pointer) types have a postfix.
2057               // In that case we don't want the space but expect something
2058               // like prefix is "int (*" and postfix is ") [1]".
2059               // We do want the space if this pointer is qualified.
2060               if (return_type_postfix.size() == 0 ||
2061                   (prefix.size() > 0 && *prefix.rbegin() != '*'))
2062                 prefix += ' ';
2063               prefix += '(';
2064               string_type bare_function_type;
2065               if (!decode_bare_function_type(bare_function_type)
2066                   // substitution: "<B>" (<B> recursive).
2067                   || eat_current() != 'E')
2068               {
2069                 failure = true;
2070                 break;
2071               }
2072               add_substitution(start_pos, type);  // Substitution: "F<R><B>E".
2073               qualifiers->decode_qualifiers(prefix, postfix);
2074                   // substitution: all qualified types, if any.
2075               postfix += ")";
2076               if (extern_C)
2077                 postfix += " [extern \"C\"] ";
2078               postfix += bare_function_type;
2079               postfix += return_type_postfix;
2080               break;
2081             }
2082             case 'T':
2083               if (!decode_template_param(prefix, qualifiers))
2084               {
2085                 failure = true;
2086                 break;
2087               }
2088               if (current() == 'I')
2089               {
2090                 add_substitution(start_pos, template_template_param);
2091                     // substitution: "<template-template-param>".
2092                 if (!decode_template_args(prefix))
2093                 {
2094                   failure = true;
2095                   break;
2096                 }
2097               }
2098               if (!recursive_template_param_or_substitution_call
2099                   && qualifiers->suppressed())
2100               {
2101                 add_substitution(start_pos, type);
2102                     // substitution: "<template-param>" or
2103                     // "<template-template-param> <template-args>".
2104                 qualifiers->decode_qualifiers(prefix, postfix);
2105                     // substitution: all qualified types, if any.
2106               }
2107               break;
2108             case 'S':
2109               if (M_pos >= M_maxpos)
2110               {
2111                 failure = true;
2112                 break;
2113               }
2114               if (M_str[M_pos + 1] != 't')
2115               {
2116                 if (!decode_substitution(prefix, qualifiers))
2117                 {
2118                   failure = true;
2119                   break;
2120                 }
2121                 if (current() == 'I')
2122                 {
2123                   if (!decode_template_args(prefix))
2124                   {
2125                     failure = true;
2126                     break;
2127                   }
2128                   if (!recursive_template_param_or_substitution_call
2129                       && qualifiers->suppressed())
2130                     add_substitution(start_pos, type);
2131                         // Substitution:
2132                         //   "<template-template-param> <template-args>".
2133                 }
2134                 if (!recursive_template_param_or_substitution_call
2135                     && qualifiers->suppressed())
2136                   qualifiers->decode_qualifiers(prefix, postfix);
2137                       // Substitution: all qualified types, if any.
2138                 break;
2139               }
2140               /* Fall-through for St */
2141             case 'N':
2142             case 'Z':
2143             case '0':
2144             case '1':
2145             case '2':
2146             case '3':
2147             case '4':
2148             case '5':
2149             case '6':
2150             case '7':
2151             case '8':
2152             case '9':
2153               // <Q><T>                 ==> T Q
2154               //     substitutions: "<T>" (<T> recursive).
2155               if (!decode_class_enum_type(prefix))
2156               {
2157                 failure = true;
2158                 break;
2159               }
2160               if (!recursive_template_param_or_substitution_call)
2161               {
2162                 add_substitution(start_pos, type);
2163                     // substitution: "<class-enum-type>".
2164                 qualifiers->decode_qualifiers(prefix, postfix);
2165                     // substitution: all qualified types, if any.
2166               }
2167               else
2168                 qualifiers->printing_suppressed();
2169               break;
2170             default:
2171               // <Q><T>                 ==> T Q
2172               //     substitutions: "<T>" (<T> recursive).
2173               if (!decode_builtin_type(prefix))
2174               {
2175                 failure = true;
2176                 break;
2177               }
2178               // If decode_type was called from decode_template_param then we
2179               // need to suppress calling qualifiers here in order to get a
2180               // substitution added anyway (for the <template-param>).
2181               if (!recursive_template_param_or_substitution_call)
2182                 qualifiers->decode_qualifiers(prefix, postfix);
2183               else
2184                 qualifiers->printing_suppressed();
2185               break;
2186           }
2187         }
2188     decode_type_exit:
2189         --M_inside_type;
2190         if (!recursive_template_param_or_substitution_call)
2191         {
2192           qualifiers->~qualifier_list<Allocator>();
2193           M_qualifier_list_alloc.deallocate(qualifiers, 1);
2194         }
2195         if (failure)
2196           _GLIBCXX_DEMANGLER_FAILURE;
2197         _GLIBCXX_DEMANGLER_RETURN2;
2198       }
2199
2200     // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
2201     //               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
2202     //
2203     // <prefix> ::= <prefix> <unqualified-name>
2204     //          ::= <template-prefix> <template-args>
2205     //          ::= <template-param>
2206     //          ::= # empty
2207     //          ::= <substitution>
2208     //
2209     // <template-prefix> ::= <prefix> <template unqualified-name>
2210     //                   ::= <template-param>
2211     //                   ::= <substitution>
2212     //
2213     template<typename Tp, typename Allocator>
2214       bool
2215       session<Tp, Allocator>::decode_nested_name(string_type& output,
2216                                              string_type& qualifiers)
2217       {
2218         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_nested_name");
2219
2220         if (current() != 'N' || M_pos >= M_maxpos)
2221           _GLIBCXX_DEMANGLER_FAILURE;
2222
2223         // <CV-qualifiers> ::= [r] [V] [K]  # restrict (C99), volatile, const
2224         char const* qualifiers_start = &M_str[M_pos + 1];
2225         for (char c = next(); c == 'K' || c == 'V' || c == 'r'; c = next());
2226         for (char const* qualifier_ptr = &M_str[M_pos - 1];
2227              qualifier_ptr >= qualifiers_start; --qualifier_ptr)
2228           switch(*qualifier_ptr)
2229           {
2230             case 'K':
2231               qualifiers += " const";
2232               break;
2233             case 'V':
2234               qualifiers += " volatile";
2235               break;
2236             case 'r':
2237               qualifiers += " restrict";
2238               break;
2239           }
2240
2241         int number_of_prefixes = 0;
2242         int substitution_start = M_pos;
2243         for(;;)
2244         {
2245           ++number_of_prefixes;
2246           if (current() == 'S')
2247           {
2248             if (!decode_substitution(output))
2249               _GLIBCXX_DEMANGLER_FAILURE;
2250           }
2251           else if (current() == 'I')
2252           {
2253             if (!decode_template_args(output))
2254               _GLIBCXX_DEMANGLER_FAILURE;
2255             if (current() != 'E')
2256             {
2257               // substitution: "<template-prefix> <template-args>".
2258               add_substitution(substitution_start, nested_name_prefix,
2259                                number_of_prefixes);
2260             }
2261           }
2262           else
2263           {
2264             if (current() == 'T')
2265             {
2266               if (!decode_template_param(output))
2267                 _GLIBCXX_DEMANGLER_FAILURE;
2268             }
2269             else if (!decode_unqualified_name(output))
2270               _GLIBCXX_DEMANGLER_FAILURE;
2271             if (current() != 'E')
2272             {
2273               // substitution: "<prefix> <unqualified-name>" or
2274               // "<prefix> <template unqualified-name>".
2275               add_substitution(substitution_start,
2276                   (current() == 'I') ?  nested_name_template_prefix
2277                                      : nested_name_prefix,
2278                   number_of_prefixes);
2279             }
2280           }
2281           if (current() == 'E')
2282           {
2283             eat_current();
2284             _GLIBCXX_DEMANGLER_RETURN;
2285           }
2286           if (current() != 'I')
2287             output += "::";
2288           else if (M_template_args_need_space)
2289             output += ' ';
2290           M_template_args_need_space = false;
2291         }
2292         _GLIBCXX_DEMANGLER_FAILURE;
2293       }
2294
2295     // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2296     //              := Z <function encoding> E s [<discriminator>]
2297     // <discriminator> := _ <non-negative number>
2298     //
2299     template<typename Tp, typename Allocator>
2300       bool
2301       session<Tp, Allocator>::decode_local_name(string_type& output)
2302       {
2303         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_local_name");
2304         if (current() != 'Z' || M_pos >= M_maxpos)
2305           _GLIBCXX_DEMANGLER_FAILURE;
2306         if ((M_pos += decode_encoding(output, M_str + M_pos + 1,
2307                 M_maxpos - M_pos, M_implementation_details) + 1) < 0 ||
2308                 eat_current() != 'E')
2309           _GLIBCXX_DEMANGLER_FAILURE;
2310         output += "::";
2311         if (current() == 's')
2312         {
2313           eat_current();
2314           output += "string literal";
2315         }
2316         else
2317         {
2318           string_type nested_name_qualifiers;
2319           if (!decode_name(output, nested_name_qualifiers))
2320             _GLIBCXX_DEMANGLER_FAILURE;
2321           output += nested_name_qualifiers;
2322         }
2323         string_type discriminator;
2324         if (current() == '_' && next() != 'n' && !decode_number(discriminator))
2325           _GLIBCXX_DEMANGLER_FAILURE;
2326         _GLIBCXX_DEMANGLER_RETURN;
2327       }
2328
2329     // <source-name> ::= <positive length number> <identifier>
2330     //
2331     template<typename Tp, typename Allocator>
2332       bool
2333       session<Tp, Allocator>::decode_source_name(string_type& output)
2334       {
2335         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_source_name");
2336         int length = current() - '0';
2337         if (length < 1 || length > 9)
2338           _GLIBCXX_DEMANGLER_FAILURE;
2339         while(isdigit(next()))
2340           length = 10 * length + current() - '0';
2341         char const* ptr = &M_str[M_pos];
2342         if (length > 11 && !strncmp(ptr, "_GLOBAL_", 8) && ptr[9] == 'N'
2343             && ptr[8] == ptr[10])
2344         {
2345           output += "(anonymous namespace)";
2346           if ((M_pos += length) > M_maxpos + 1)
2347             _GLIBCXX_DEMANGLER_FAILURE;
2348         }
2349         else
2350           while(length--)
2351           {
2352             if (current() == 0)
2353               _GLIBCXX_DEMANGLER_FAILURE;
2354             output += eat_current();
2355           }
2356         _GLIBCXX_DEMANGLER_RETURN;
2357       }
2358
2359     // <unqualified-name> ::= <operator-name>   # Starts with lower case.
2360     //                    ::= <ctor-dtor-name>  # Starts with 'C' or 'D'.
2361     //                    ::= <source-name>     # Starts with a digit.
2362     //
2363     template<typename Tp, typename Allocator>
2364       bool
2365       session<Tp, Allocator>::decode_unqualified_name(string_type& output)
2366       {
2367         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_unqualified_name");
2368         if (M_inside_template_args)
2369         {
2370           if (!decode_source_name(output))
2371             _GLIBCXX_DEMANGLER_FAILURE;
2372         }
2373         else if (isdigit(current()))
2374         {
2375           bool recursive_unqualified_name = (&M_function_name == &output);
2376           // This can be a recursive call when we are decoding
2377           // an <operator-name> that is a cast operator for a some
2378           // <unqualified-name>; for example "operator Foo()".
2379           // In that case this is thus not a ctor or dtor and we
2380           // are not interested in updating M_function_name.
2381           if (!recursive_unqualified_name)
2382             M_function_name.clear();
2383           M_name_is_template = false;
2384           M_name_is_cdtor = false;
2385           M_name_is_conversion_operator = false;
2386           if (!decode_source_name(M_function_name))
2387             _GLIBCXX_DEMANGLER_FAILURE;
2388           if (!recursive_unqualified_name)
2389             output += M_function_name;
2390         }
2391         else if (islower(current()))
2392         {
2393           M_function_name.clear();
2394           M_name_is_template = false;
2395           M_name_is_cdtor = false;
2396           M_name_is_conversion_operator = false;
2397           if (!decode_operator_name(M_function_name))
2398             _GLIBCXX_DEMANGLER_FAILURE;
2399           output += M_function_name;
2400         }
2401         else if (current() == 'C' || current() == 'D')
2402         {
2403           // <ctor-dtor-name> ::=
2404           //   C1       # complete object (in-charge) constructor
2405           //   C2       # base object (not-in-charge) constructor
2406           //   C3       # complete object (in-charge) allocating constructor
2407           //   D0       # deleting (in-charge) destructor
2408           //   D1       # complete object (in-charge) destructor
2409           //   D2       # base object (not-in-charge) destructor
2410           //
2411           if (current() == 'C')
2412           {
2413             char c = next();
2414             if (c < '1' || c > '3')
2415               _GLIBCXX_DEMANGLER_FAILURE;
2416           }
2417           else
2418           {
2419             char c = next();
2420             if (c < '0' || c > '2')
2421               _GLIBCXX_DEMANGLER_FAILURE;
2422             output += '~';
2423             M_saw_destructor = true;
2424           }
2425           M_name_is_cdtor = true;
2426           eat_current();
2427           output += M_function_name;
2428         }
2429         else
2430           _GLIBCXX_DEMANGLER_FAILURE;
2431         _GLIBCXX_DEMANGLER_RETURN;
2432       }
2433
2434     // <unscoped-name> ::=
2435     //   <unqualified-name>             # Starts not with an 'S'
2436     //   St <unqualified-name>          # ::std::
2437     //
2438     template<typename Tp, typename Allocator>
2439       bool
2440       session<Tp, Allocator>::decode_unscoped_name(string_type& output)
2441       {
2442         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_unscoped_name");
2443         if (current() == 'S')
2444         {
2445           if (next() != 't')
2446             _GLIBCXX_DEMANGLER_FAILURE;
2447           eat_current();
2448           output += "std::";
2449         }
2450         decode_unqualified_name(output);
2451         _GLIBCXX_DEMANGLER_RETURN;
2452       }
2453
2454     // <name> ::=
2455     //   <nested-name>                          # Starts with 'N'
2456     //   <unscoped-template-name> <template-args> # idem
2457     //   <local-name>                           # Starts with 'Z'
2458     //   <unscoped-name>                        # Starts with 'S', 'C', 'D',
2459     //                                          # a digit or a lower case
2460     //                                          # character.
2461     //
2462     // <unscoped-template-name> ::= <unscoped-name>
2463     //                          ::= <substitution>
2464     template<typename Tp, typename Allocator>
2465       bool
2466       session<Tp, Allocator>::decode_name(string_type& output,
2467                                       string_type& nested_name_qualifiers)
2468       {
2469         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_name");
2470         int substitution_start = M_pos;
2471         if (current() == 'S' && (M_pos >= M_maxpos || M_str[M_pos + 1] != 't'))
2472         {
2473           if (!decode_substitution(output))
2474             _GLIBCXX_DEMANGLER_FAILURE;
2475         }
2476         else if (current() == 'N')
2477         {
2478           decode_nested_name(output, nested_name_qualifiers);
2479           _GLIBCXX_DEMANGLER_RETURN;
2480         }
2481         else if (current() == 'Z')
2482         {
2483           decode_local_name(output);
2484           _GLIBCXX_DEMANGLER_RETURN;
2485         }
2486         else if (!decode_unscoped_name(output))
2487           _GLIBCXX_DEMANGLER_FAILURE;
2488         if (current() == 'I')
2489         {
2490           // Must have been an <unscoped-template-name>.
2491           add_substitution(substitution_start, unscoped_template_name);
2492           if (!decode_template_args(output))
2493             _GLIBCXX_DEMANGLER_FAILURE;
2494         }
2495         M_template_args_need_space = false;
2496         _GLIBCXX_DEMANGLER_RETURN;
2497       }
2498
2499     // <call-offset> ::= h <nv-offset> _
2500     //               ::= v <v-offset> _
2501     // <nv-offset>   ::= <offset number>
2502     //     non-virtual base override
2503     //
2504     // <v-offset>    ::= <offset number> _ <virtual offset number>
2505     //     virtual base override, with vcall offset
2506     template<typename Tp, typename Allocator>
2507       bool
2508       session<Tp, Allocator>::decode_call_offset(string_type&
2509 #if _GLIBCXX_DEMANGLER_CWDEBUG
2510           output
2511 #endif
2512           )
2513       {
2514         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_call_offset");
2515         if (current() == 'h')
2516         {
2517           string_type dummy;
2518           eat_current();
2519           if (decode_number(dummy) && current() == '_')
2520           {
2521             eat_current();
2522             _GLIBCXX_DEMANGLER_RETURN;
2523           }
2524         }
2525         else if (current() == 'v')
2526         {
2527           string_type dummy;
2528           eat_current();
2529           if (decode_number(dummy) && current() == '_')
2530           {
2531             eat_current();
2532             if (decode_number(dummy) && current() == '_')
2533             {
2534               eat_current();
2535               _GLIBCXX_DEMANGLER_RETURN;
2536             }
2537           }
2538         }
2539         _GLIBCXX_DEMANGLER_FAILURE;
2540       }
2541
2542     //
2543     // <special-name> ::=
2544     //   TV <type>                      # virtual table
2545     //   TT <type>                      # VTT structure (construction
2546     //                                    vtable index).
2547     //   TI <type>                      # typeinfo structure
2548     //   TS <type>                      # typeinfo name (null-terminated
2549     //                                    byte string).
2550     //   GV <object name>               # Guard variable for one-time
2551     //                                    initialization of static objects in
2552     //                                    a local scope.
2553     //   T <call-offset> <base encoding># base is the nominal target function
2554     //                                    of thunk.
2555     //   Tc <call-offset> <call-offset> <base encoding> # base is the nominal
2556     //                                    target function of thunk; first
2557     //                                    call-offset is 'this' adjustment;
2558     //                                    second call-offset is result
2559     //                                    adjustment
2560     //
2561     template<typename Tp, typename Allocator>
2562       bool
2563       session<Tp, Allocator>::decode_special_name(string_type& output)
2564       {
2565         _GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_special_name");
2566         if (current() == 'G')
2567         {
2568           if (next() != 'V')
2569             _GLIBCXX_DEMANGLER_FAILURE;
2570           output += "guard variable for ";
2571           string_type nested_name_qualifiers;
2572           eat_current();
2573           if (!decode_name(output, nested_name_qualifiers))
2574             _GLIBCXX_DEMANGLER_FAILURE;
2575           output += nested_name_qualifiers;
2576           _GLIBCXX_DEMANGLER_RETURN;
2577         }
2578         else if (current() != 'T')
2579           _GLIBCXX_DEMANGLER_FAILURE;
2580         switch(next())
2581         {
2582           case 'V':
2583             output += "vtable for ";
2584             eat_current();
2585             decode_type(output);
2586             _GLIBCXX_DEMANGLER_RETURN;
2587           case 'T':
2588             output += "VTT for ";
2589             eat_current();
2590             decode_type(output);
2591             _GLIBCXX_DEMANGLER_RETURN;
2592           case 'I':
2593             output += "typeinfo for ";
2594             eat_current();
2595             decode_type(output);
2596             _GLIBCXX_DEMANGLER_RETURN;
2597           case 'S':
2598             output += "typeinfo name for ";
2599             eat_current();
2600             decode_type(output);
2601             _GLIBCXX_DEMANGLER_RETURN;
2602           case 'c':
2603             output += "covariant return thunk to ";
2604             if (!decode_call_offset(output)
2605                 || !decode_call_offset(output)
2606                 || (M_pos += decode_encoding(output, M_str + M_pos,
2607                     M_maxpos - M_pos + 1, M_implementation_details)) < 0)
2608               _GLIBCXX_DEMANGLER_FAILURE;
2609             _GLIBCXX_DEMANGLER_RETURN;
2610           case 'C':             // GNU extension?
2611           {
2612             string_type first;
2613             output += "construction vtable for ";
2614             eat_current();
2615             if (!decode_type(first))
2616               _GLIBCXX_DEMANGLER_FAILURE;
2617             while(isdigit(current()))
2618               eat_current();
2619             if (eat_current() != '_')
2620               _GLIBCXX_DEMANGLER_FAILURE;
2621             if (!decode_type(output))
2622               _GLIBCXX_DEMANGLER_FAILURE;
2623             output += "-in-";
2624             output += first;
2625             _GLIBCXX_DEMANGLER_RETURN;
2626           }
2627           default:
2628             if (current() == 'v')
2629               output += "virtual thunk to ";
2630             else
2631               output += "non-virtual thunk to ";
2632             if (!decode_call_offset(output)
2633                 || (M_pos += decode_encoding(output, M_str + M_pos,
2634                     M_maxpos - M_pos + 1, M_implementation_details)) < 0)
2635               _GLIBCXX_DEMANGLER_FAILURE;
2636             _GLIBCXX_DEMANGLER_RETURN;
2637         }
2638       }
2639
2640     // <encoding> ::=
2641     //   <function name> <bare-function-type>   # Starts with 'C', 'D', 'N',
2642     //                                            'S', a digit or a lower case
2643     //                                            character.
2644     //   <data name>                            # Idem.
2645     //   <special-name>                         # Starts with 'T' or 'G'.
2646     template<typename Tp, typename Allocator>
2647       int
2648       session<Tp, Allocator>::decode_encoding(string_type& output,
2649           char const* in, int len, implementation_details const& id)
2650       {
2651 #if _GLIBCXX_DEMANGLER_CWDEBUG
2652         _GLIBCXX_DEMANGLER_DOUT(dc::demangler,
2653             "Output thus far: \"" << output << '"');
2654         string_type input(in, len > 0x40000000 ? strlen(in) : len);
2655         _GLIBCXX_DEMANGLER_DOUT(
2656             dc::demangler, "Entering decode_encoding(\"" << input << "\")");
2657 #endif
2658         if (len <= 0)
2659           return INT_MIN;
2660         session<Tp, Allocator> demangler_session(in, len, id);
2661         string_type nested_name_qualifiers;
2662         int saved_pos;
2663         demangler_session.store(saved_pos);
2664         if (demangler_session.decode_special_name(output))
2665           return demangler_session.M_pos;
2666         demangler_session.restore(saved_pos);
2667         string_type name;
2668         if (!demangler_session.decode_name(name, nested_name_qualifiers))
2669           return INT_MIN;
2670         if (demangler_session.current() == 0
2671             || demangler_session.current() == 'E')
2672         {
2673           output += name;
2674           output += nested_name_qualifiers;
2675           return demangler_session.M_pos;
2676         }
2677         // Must have been a <function name>.
2678         string_type return_type_postfix;
2679         if (demangler_session.M_name_is_template
2680             && !(demangler_session.M_name_is_cdtor
2681                  || demangler_session.M_name_is_conversion_operator))
2682         {
2683           // Return type of function
2684           if (!demangler_session.decode_type_with_postfix(output,
2685               return_type_postfix))
2686             return INT_MIN;
2687           output += ' ';
2688         }
2689         output += name;
2690         if (!demangler_session.decode_bare_function_type(output))
2691           return INT_MIN;
2692         output += nested_name_qualifiers;
2693         output += return_type_postfix;
2694         return demangler_session.M_pos;
2695       }
2696
2697     } // namespace demangler
2698
2699   // Public interface
2700   template<typename Tp, typename Allocator>
2701     struct demangle
2702     {
2703       typedef typename Allocator::template rebind<char>::other char_Allocator;
2704       typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
2705           string_type;
2706       static string_type symbol(char const* in,
2707                                 demangler::implementation_details const& id);
2708       static string_type type(char const* in,
2709                               demangler::implementation_details const& id);
2710     };
2711
2712   // demangle::symbol()
2713   //
2714   // Demangle `input' which should be a mangled function name as for
2715   // instance returned by nm(1).
2716   template<typename Tp, typename Allocator>
2717     typename demangle<Tp, Allocator>::string_type
2718     demangle<Tp, Allocator>::symbol(char const* input,
2719                                 demangler::implementation_details const& id)
2720     {
2721       // <mangled-name> ::= _Z <encoding>
2722       // <mangled-name> ::= _GLOBAL_ _<type>_ <disambiguation part>
2723       //                    <type> can be I or D (GNU extension)
2724       typedef demangler::session<Tp, Allocator> demangler_type;
2725       string_type result;
2726       bool failure = (input[0] != '_');
2727
2728       if (!failure)
2729       {
2730         if (input[1] == 'G')
2731         {
2732           if (!strncmp(input, "_GLOBAL__", 9)
2733               && (input[9] == 'D' || input[9] == 'I')
2734               && input[10] == '_')
2735           {
2736             if (input[9] == 'D')
2737               result.assign("global destructors keyed to ", 28);
2738             else
2739               result.assign("global constructors keyed to ", 29);
2740             // Output the disambiguation part as-is.
2741             result += input + 11;
2742           }
2743           else
2744             failure = true;
2745         }
2746         else if (input[1] == 'Z')
2747         {
2748           int cnt =
2749               demangler_type::decode_encoding(result, input + 2, INT_MAX, id);
2750           if (cnt < 0 || input[cnt + 2] != 0)
2751             failure = true;
2752         }
2753         else
2754           failure = true;
2755       }
2756
2757       // Failure to demangle, return the mangled name.
2758       if (failure)
2759         result.assign(input, strlen(input));
2760
2761       return result;
2762     }
2763
2764   // demangle::type()
2765   // Demangle `input' which must be a zero terminated mangled type
2766   // name as for instance returned by std::type_info::name().
2767   template<typename Tp, typename Allocator>
2768     typename demangle<Tp, Allocator>::string_type
2769     demangle<Tp, Allocator>::type(char const* input,
2770                               demangler::implementation_details const& id)
2771     {
2772       std::basic_string<char, std::char_traits<char>, Allocator> result;
2773       if (input == NULL)
2774         result = "(null)";
2775       else
2776       {
2777         demangler::session<Tp, Allocator> demangler_session(input, INT_MAX, id);
2778         if (!demangler_session.decode_type(result)
2779             || demangler_session.remaining_input_characters())
2780         {
2781           // Failure to demangle, return the mangled name.
2782           result = input;
2783         }
2784       }
2785       return result;
2786     }
2787 } // namespace __gnu_cxx
2788
2789 #endif // __DEMANGLE_H