OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / demangle.h
1 // C++ IA64 / g++ v3 demangler  -*- C++ -*-
2
3 // Copyright (C) 2003 Free Software Foundation, Inc.
4 // Written by Carlo Wood <carlo@alinoe.com>
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
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 #ifndef __DEMANGLER_H
32 #define __DEMANGLER_H 1
33
34 #include <limits>
35 #include <vector>
36 #include <string>
37 #include <cctype>
38
39 #ifndef _GLIBCPP_DEMANGLER_DEBUG
40 #define _GLIBCPP_DEMANGLER_CWDEBUG 0
41 #define _GLIBCPP_DEMANGLER_DEBUG(x)
42 #define _GLIBCPP_DEMANGLER_DOUT(cntrl, data)
43 #define _GLIBCPP_DEMANGLER_DOUT_ENTERING(x)
44 #define _GLIBCPP_DEMANGLER_DOUT_ENTERING2(x)
45 #define _GLIBCPP_DEMANGLER_RETURN \
46     return M_result
47 #define _GLIBCPP_DEMANGLER_RETURN2 \
48     return M_result
49 #define _GLIBCPP_DEMANGLER_FAILURE \
50     do { M_result = false; return false; } while(0)
51 #else
52 #define _GLIBCPP_DEMANGLER_CWDEBUG 1
53 #endif
54
55 // The following defines change the behaviour of the demangler.  The
56 // default behaviour is that none of these macros is defined.
57
58 // _GLIBCPP_DEMANGLER_STYLE_VOID
59 // Default behaviour:                                   int f()
60 // Uses (void) instead of ():                           int f(void)
61
62 // _GLIBCPP_DEMANGLER_STYLE_LITERAL
63 // Default behaviour:                                   (long)13, 
64 //                                                      (unsigned long long)19
65 // Use extensions 'u', 'l' and 'll' for integral
66 // literals (as in template arguments):                 13l, 19ull
67
68 // _GLIBCPP_DEMANGLER_STYLE_LITERAL_INT
69 // Default behaviour:                                   4
70 // Use also an explicit cast for int in literals:       (int)4
71
72 namespace __gnu_cxx
73 {
74   namespace demangler
75   {
76
77     enum substitution_nt
78     {
79       type,
80       template_template_param,
81       nested_name_prefix,
82       nested_name_template_prefix,
83       unscoped_template_name,
84     };
85
86     struct substitution_st
87     {
88       int M_start_pos;
89       substitution_nt M_type;
90       int M_number_of_prefixes;
91       
92       substitution_st(int start_pos,
93                       substitution_nt type,
94                       int number_of_prefixes)
95       : M_start_pos(start_pos), M_type(type),
96         M_number_of_prefixes(number_of_prefixes)
97       { }
98     };
99
100     enum simple_qualifier_nt
101     {
102       complex_or_imaginary = 'G',
103       pointer = 'P',
104       reference = 'R'
105     };
106
107     enum cv_qualifier_nt
108     {
109       cv_qualifier = 'K'
110     };
111
112     enum param_qualifier_nt
113     {
114       vendor_extension = 'U',
115       array = 'A',
116       pointer_to_member = 'M'
117     };
118
119     template<typename Allocator>
120       class qualifier;
121
122     template<typename Allocator>
123       class qualifier_list;
124
125     template<typename Allocator>
126       class session;
127
128     template<typename Allocator>
129       class qualifier
130       {
131         typedef std::basic_string<char, std::char_traits<char>, Allocator>
132             string_type;
133
134       private:
135         char M_qualifier1;
136         char M_qualifier2;
137         char M_qualifier3;
138         mutable unsigned char M_cnt;
139         string_type M_optional_type;
140         int M_start_pos;
141         bool M_part_of_substitution;
142
143       public:
144         qualifier(int start_pos,
145                   simple_qualifier_nt simple_qualifier,
146                   int inside_substitution)
147         : M_qualifier1(simple_qualifier),
148           M_start_pos(start_pos),
149           M_part_of_substitution(inside_substitution)
150         { }
151
152         qualifier(int start_pos,
153                   cv_qualifier_nt cv_qualifier,
154                   char const* start,
155                   int count,
156                   int inside_substitution)
157         : M_qualifier1(start[0]),
158           M_qualifier2((count > 1) ? start[1] : '\0'),
159           M_qualifier3((count > 2) ? start[2] : '\0'),
160           M_start_pos(start_pos),
161           M_part_of_substitution(inside_substitution)
162         { }
163
164         qualifier(int start_pos,
165                   param_qualifier_nt param_qualifier,
166                   string_type optional_type,
167                   int inside_substitution)
168         : M_qualifier1(param_qualifier),
169           M_optional_type(optional_type),
170           M_start_pos(start_pos),
171           M_part_of_substitution(inside_substitution)
172         { }
173
174         int
175         get_start_pos(void) const
176         { return M_start_pos; }
177
178         char
179         first_qualifier(void) const
180         { M_cnt = 1; return M_qualifier1; }
181
182         char
183         next_qualifier(void) const
184         {
185           return (++M_cnt == 2) ? M_qualifier2
186                                 : ((M_cnt == 3) ? M_qualifier3 : 0);
187         }
188
189         string_type const&
190         get_optional_type(void) const
191         { return M_optional_type; }
192
193         bool
194         part_of_substitution(void) const
195         { return M_part_of_substitution; }
196
197       };
198
199     template<typename Allocator>
200       class qualifier_list
201       {
202         typedef std::basic_string<char, std::char_traits<char>, Allocator>
203           string_type;
204
205       private:
206         bool M_printing_suppressed;
207         std::vector<qualifier<Allocator>, Allocator> M_qualifier_starts;
208         session<Allocator>& M_demangler;
209
210       public:
211         qualifier_list(session<Allocator>& demangler_obj)
212         : M_printing_suppressed(false), M_demangler(demangler_obj)
213         { }
214
215         void
216         add_qualifier_start(simple_qualifier_nt simple_qualifier,
217                             int start_pos,
218                             int inside_substitution)
219         { M_qualifier_starts.
220               push_back(qualifier<Allocator>(start_pos,
221                   simple_qualifier, inside_substitution)); }
222
223         void
224         add_qualifier_start(cv_qualifier_nt cv_qualifier,
225                             int start_pos,
226                             int count,
227                             int inside_substitution)
228         { M_qualifier_starts.
229               push_back(qualifier<Allocator>(start_pos,
230                     cv_qualifier, &M_demangler.M_str[start_pos],
231                     count, inside_substitution)); }
232
233         void
234         add_qualifier_start(param_qualifier_nt param_qualifier,
235                             int start_pos,
236                             string_type optional_type,
237                             int inside_substitution)
238         { M_qualifier_starts.
239               push_back(qualifier<Allocator>(start_pos,
240                     param_qualifier, optional_type, inside_substitution)); }
241
242         void
243         decode_qualifiers(string_type& prefix,
244                           string_type& postfix,
245                           bool member_function_pointer_qualifiers);
246
247         bool
248         suppressed(void) const
249         { return M_printing_suppressed; }
250
251         void
252         printing_suppressed(void)
253         { M_printing_suppressed = true; }
254
255         size_t
256         size(void) const
257         { return M_qualifier_starts.size(); }
258
259       };
260
261     template<typename Allocator>
262       class session
263       {
264         friend class qualifier_list<Allocator>;
265         typedef std::basic_string<char, std::char_traits<char>, Allocator>
266             string_type;
267
268       private:
269         char const* M_str;
270         int M_pos;
271         int M_maxpos;
272         bool M_result;
273         int M_inside_template_args;
274         int M_inside_type;
275         int M_inside_substitution;
276         bool M_saw_destructor;
277         bool M_name_is_cdtor;
278         bool M_name_is_template;
279         bool M_name_is_conversion_operator;
280         bool M_template_args_need_space;
281         string_type M_function_name;
282         std::vector<int, Allocator> M_template_arg_pos;
283         int M_template_arg_pos_offset;
284         std::vector<substitution_st, Allocator> M_substitutions_pos;
285 #if _GLIBCPP_DEMANGLER_CWDEBUG
286         bool M_inside_add_substitution;
287 #endif
288
289       public:
290         explicit session(char const* in, int len)
291         : M_str(in), M_pos(0), M_maxpos(len - 1), M_result(true),
292           M_inside_template_args(0), M_inside_type(0),
293           M_inside_substitution(0), M_saw_destructor(false),
294           M_name_is_cdtor(false), M_name_is_template(false),
295           M_name_is_conversion_operator(false),
296           M_template_args_need_space(false), M_template_arg_pos_offset(0)
297 #if _GLIBCPP_DEMANGLER_CWDEBUG
298           , M_inside_add_substitution(false)
299 #endif
300         { }
301
302         static int
303         decode_encoding(string_type& output, char const* input, int len);
304
305         bool
306         decode_type_with_postfix(string_type& prefix,
307                                  string_type& postfix,
308                     qualifier_list<Allocator>* qualifiers = NULL);
309
310         bool
311         decode_type(string_type& output,
312                     qualifier_list<Allocator>* qualifiers = NULL)
313         {
314           string_type postfix;
315           bool res = decode_type_with_postfix(output, postfix, qualifiers);
316           output += postfix;
317           return res;
318         }
319
320         bool
321         remaining_input_characters(void) const
322         { return current() != 0; }
323
324       private:
325         char
326         current(void) const
327         { return (M_pos > M_maxpos) ? 0 : M_str[M_pos]; }
328
329         char
330         next(void)
331         { return (M_pos >= M_maxpos) ? 0 : M_str[++M_pos]; }
332
333         char
334         eat_current(void)
335         { return (M_pos > M_maxpos) ? 0 : M_str[M_pos++]; }
336
337         void
338         store(int& saved_pos)
339         { saved_pos = M_pos; }
340
341         void
342         restore(int saved_pos)
343         { M_pos = saved_pos; M_result = true; }
344
345         void
346         add_substitution(int start_pos,
347                          substitution_nt sub_type,
348                          int number_of_prefixes);
349
350         bool decode_bare_function_type(string_type& output);
351         bool decode_builtin_type(string_type& output);
352         bool decode_call_offset(string_type& output);
353         bool decode_class_enum_type(string_type& output);
354         bool decode_expression(string_type& output);
355         bool decode_literal(string_type& output);
356         bool decode_local_name(string_type& output);
357         bool decode_name(string_type& output,
358             string_type& nested_name_qualifiers);
359         bool decode_nested_name(string_type& output,
360             string_type& qualifiers);
361         bool decode_number(string_type& output);
362         bool decode_operator_name(string_type& output);
363         bool decode_source_name(string_type& output);
364         bool decode_substitution(string_type& output,
365             qualifier_list<Allocator>* qualifiers = NULL);
366         bool decode_template_args(string_type& output);
367         bool decode_template_param(string_type& output,
368             qualifier_list<Allocator>* qualifiers = NULL);
369         bool decode_unqualified_name(string_type& output);
370         bool decode_unscoped_name(string_type& output);
371         bool decode_decimal_integer(string_type& output);
372         bool decode_special_name(string_type& output);
373       };
374
375     template<typename Allocator>
376 #if !_GLIBCPP_DEMANGLER_CWDEBUG
377       inline
378 #endif
379       void
380       session<Allocator>::add_substitution(int start_pos,
381                                            substitution_nt sub_type,
382                                            int number_of_prefixes = 0)
383       {
384         if (!M_inside_substitution)
385         {
386 #if _GLIBCPP_DEMANGLER_CWDEBUG
387           if (M_inside_add_substitution)
388             return;
389 #endif
390           M_substitutions_pos.
391               push_back(substitution_st(start_pos,
392                   sub_type, number_of_prefixes));
393 #if _GLIBCPP_DEMANGLER_CWDEBUG
394           if (!DEBUGCHANNELS::dc::demangler.is_on())
395             return;
396           string_type substitution_name("S");
397           int n = M_substitutions_pos.size() - 1;
398           if (n > 0)
399             substitution_name += (n <= 10) ? (char)(n + '0' - 1)
400                                            : (char)(n + 'A' - 11);
401           substitution_name += '_';
402           string_type subst;
403           int saved_pos = M_pos;
404           M_pos = start_pos;
405           M_inside_add_substitution = true;
406           _GLIBCPP_DEMANGLER_DEBUG( dc::demangler.off() );
407           switch(sub_type)
408           {
409             case type:
410               decode_type(subst);
411               break;
412             case template_template_param:
413               decode_template_param(subst);
414               break;
415             case nested_name_prefix:
416             case nested_name_template_prefix:
417               for (int cnt = number_of_prefixes; cnt > 0; --cnt)
418               {
419                 if (current() == 'I')
420                 {
421                   subst += ' ';
422                   decode_template_args(subst);
423                 }
424                 else
425                 {
426                   if (cnt < number_of_prefixes)
427                     subst += "::";
428                   if (current() == 'S')
429                     decode_substitution(subst);
430                   else
431                     decode_unqualified_name(subst);
432                 }
433               }
434               break;
435             case unscoped_template_name:
436               decode_unscoped_name(subst);
437               break;
438           }
439           M_pos = saved_pos;
440           _GLIBCPP_DEMANGLER_DEBUG( dc::demangler.on() );
441           _GLIBCPP_DEMANGLER_DOUT(dc::demangler,
442               "Adding substitution " << substitution_name
443               << " : " << subst
444               << " (from " << location_ct((char*)__builtin_return_address(0)
445                                           + builtin_return_address_offset)
446               << " <- " << location_ct((char*)__builtin_return_address(1)
447                                        + builtin_return_address_offset)
448               << " <- " << location_ct((char*)__builtin_return_address(2)
449                                        + builtin_return_address_offset)
450               << ").");
451           M_inside_add_substitution = false;
452 #endif
453         }
454       }
455
456     //
457     // <decimal-integer> ::= 0
458     //                   ::= 1|2|3|4|5|6|7|8|9 [<digit>+]
459     // <digit>           ::= 0|1|2|3|4|5|6|7|8|9
460     //
461     template<typename Allocator>
462       bool
463       session<Allocator>::decode_decimal_integer(string_type& output)
464       {
465         char c = current();
466         if (c == '0')
467         {
468           output += '0';
469           eat_current();
470         }
471         else if (!std::isdigit(c))
472           M_result = false;
473         else
474         {
475           do
476           {
477             output += c;
478           }
479           while (std::isdigit((c = next())));
480         }
481         return M_result;
482       }
483
484     // <number> ::= [n] <decimal-integer>
485     //
486     template<typename Allocator>
487       bool
488       session<Allocator>::decode_number(string_type& output)
489       {
490         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_number");
491         if (current() != 'n')
492           decode_decimal_integer(output);
493         else
494         {
495           output += '-';
496           eat_current();
497           decode_decimal_integer(output);
498         }
499         _GLIBCPP_DEMANGLER_RETURN;
500       }
501
502     // <builtin-type> ::= v  # void
503     //                ::= w  # wchar_t
504     //                ::= b  # bool
505     //                ::= c  # char
506     //                ::= a  # signed char
507     //                ::= h  # unsigned char
508     //                ::= s  # short
509     //                ::= t  # unsigned short
510     //                ::= i  # int
511     //                ::= j  # unsigned int
512     //                ::= l  # long
513     //                ::= m  # unsigned long
514     //                ::= x  # long long, __int64
515     //                ::= y  # unsigned long long, __int64
516     //                ::= n  # __int128
517     //                ::= o  # unsigned __int128
518     //                ::= f  # float
519     //                ::= d  # double
520     //                ::= e  # long double, __float80
521     //                ::= g  # __float128
522     //                ::= z  # ellipsis
523     //                ::= u <source-name>    # vendor extended type
524     //
525     char const* const builtin_type_c[26] =
526     {
527       "signed char",    // a
528       "bool",           // b
529       "char",           // c
530       "double",         // d
531       "long double",    // e
532       "float",          // f
533       "__float128",             // g
534       "unsigned char",  // h
535       "int",            // i
536       "unsigned int",   // j
537       NULL,                     // k
538       "long",           // l
539       "unsigned long",  // m
540       "__int128",               // n
541       "unsigned __int128",      // o
542       NULL,                     // p
543       NULL,                     // q
544       NULL,                     // r
545       "short",          // s
546       "unsigned short", // t
547       NULL,                     // u
548       "void",           // v
549       "wchar_t",                // w
550       "long long",              // x
551       "unsigned long long",     // y
552       "..."                     // z
553     };
554
555     //
556     template<typename Allocator>
557       bool
558       session<Allocator>::decode_builtin_type(string_type& output)
559       {
560         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_builtin_type");
561         char const* bt;
562         if (!islower(current()) || !(bt = builtin_type_c[current() - 'a']))
563           _GLIBCPP_DEMANGLER_FAILURE;
564         output += bt;
565         eat_current();
566         _GLIBCPP_DEMANGLER_RETURN;
567       }
568
569     // <class-enum-type> ::= <name>
570     //
571     template<typename Allocator>
572       bool
573       session<Allocator>::decode_class_enum_type(string_type& output)
574       {
575         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_class_enum_type");
576         string_type nested_name_qualifiers;
577         if (!decode_name(output, nested_name_qualifiers))
578           _GLIBCPP_DEMANGLER_FAILURE;
579         output += nested_name_qualifiers;
580         _GLIBCPP_DEMANGLER_RETURN;
581       }
582
583     // <substitution> ::=
584     //   S <seq-id> _
585     //   S_
586     //   St # ::std::
587     //   Sa # ::std::allocator
588     //   Sb # ::std::basic_string
589     //   Ss # ::std::basic_string<char, std::char_traits<char>,
590     //                            std::allocator<char> >
591     //   Si # ::std::basic_istream<char,  std::char_traits<char> >
592     //   So # ::std::basic_ostream<char,  std::char_traits<char> >
593     //   Sd # ::std::basic_iostream<char, std::char_traits<char> >
594     //
595     // <seq-id> ::=
596     //   0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
597     //       [<seq-id>] # Base 36 number
598     //
599     template<typename Allocator>
600       bool
601       session<Allocator>::decode_substitution(string_type& output,
602           qualifier_list<Allocator>* qualifiers)
603       {
604         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_substitution");
605         unsigned int value = 0;
606         char c = next();
607         if (c != '_')
608         {
609           switch(c)
610           {
611             case 'a':
612             {
613               output += "std::allocator";
614               if (!M_inside_template_args)
615               {
616                 M_function_name = "allocator";
617                 M_name_is_template = true;
618                 M_name_is_cdtor = false;
619                 M_name_is_conversion_operator = false;
620               }
621               eat_current();
622               if (qualifiers)
623                 qualifiers->printing_suppressed();
624               _GLIBCPP_DEMANGLER_RETURN;
625             }
626             case 'b':
627             {
628               output += "std::basic_string";
629               if (!M_inside_template_args)
630               {
631                 M_function_name = "basic_string";
632                 M_name_is_template = true;
633                 M_name_is_cdtor = false;
634                 M_name_is_conversion_operator = false;
635               }
636               eat_current();
637               if (qualifiers)
638                 qualifiers->printing_suppressed();
639               _GLIBCPP_DEMANGLER_RETURN;
640             }
641             case 'd':
642               output += "std::iostream";
643               if (!M_inside_template_args)
644               {
645                 M_function_name = "iostream";
646                 M_name_is_template = true;
647                 M_name_is_cdtor = false;
648                 M_name_is_conversion_operator = false;
649               }
650               eat_current();
651               if (qualifiers)
652                 qualifiers->printing_suppressed();
653               _GLIBCPP_DEMANGLER_RETURN;
654             case 'i':
655               output += "std::istream";
656               if (!M_inside_template_args)
657               {
658                 M_function_name = "istream";
659                 M_name_is_template = true;
660                 M_name_is_cdtor = false;
661                 M_name_is_conversion_operator = false;
662               }
663               eat_current();
664               if (qualifiers)
665                 qualifiers->printing_suppressed();
666               _GLIBCPP_DEMANGLER_RETURN;
667             case 'o':
668               output += "std::ostream";
669               if (!M_inside_template_args)
670               {
671                 M_function_name = "ostream";
672                 M_name_is_template = true;
673                 M_name_is_cdtor = false;
674                 M_name_is_conversion_operator = false;
675               }
676               eat_current();
677               if (qualifiers)
678                 qualifiers->printing_suppressed();
679               _GLIBCPP_DEMANGLER_RETURN;
680             case 's':
681               output += "std::string";
682               if (!M_inside_template_args)
683               {
684                 M_function_name = "string";
685                 M_name_is_template = true;
686                 M_name_is_cdtor = false;
687                 M_name_is_conversion_operator = false;
688               }
689               eat_current();
690               if (qualifiers)
691                 qualifiers->printing_suppressed();
692               _GLIBCPP_DEMANGLER_RETURN;
693             case 't':
694               output += "std";
695               eat_current();
696               if (qualifiers)
697                 qualifiers->printing_suppressed();
698               _GLIBCPP_DEMANGLER_RETURN;
699             default:
700               for(;; c = next())
701               {
702                 if (std::isdigit(c))
703                   value = value * 36 + c - '0';
704                 else if (isupper(c))
705                   value = value * 36 + c - 'A' + 10;
706                 else if (c == '_')
707                   break;
708                 else
709                   _GLIBCPP_DEMANGLER_FAILURE;
710               }
711               ++value;
712               break;
713           }
714         }
715         eat_current();
716         if (value >= M_substitutions_pos.size() ||
717             M_inside_type > 20)                 // Rather than core dump.
718           _GLIBCPP_DEMANGLER_FAILURE;
719         ++M_inside_substitution;
720         int saved_pos = M_pos;
721         substitution_st& substitution(M_substitutions_pos[value]);
722         M_pos = substitution.M_start_pos;
723         switch(substitution.M_type)
724         {
725           case type:
726             decode_type(output, qualifiers);
727             break;
728           case template_template_param:
729             decode_template_param(output, qualifiers);
730             break;
731           case nested_name_prefix:
732           case nested_name_template_prefix:
733             for (int cnt = substitution.M_number_of_prefixes; cnt > 0; --cnt)
734             {
735               if (current() == 'I')
736               {
737                 if (M_template_args_need_space)
738                   output += ' ';
739                 M_template_args_need_space = false;
740                 if (!decode_template_args(output))
741                   _GLIBCPP_DEMANGLER_FAILURE;
742               }
743               else
744               {
745                 if (cnt < substitution.M_number_of_prefixes)
746                   output += "::";
747                 if (current() == 'S')
748                 {
749                   if (!decode_substitution(output))
750                     _GLIBCPP_DEMANGLER_FAILURE;
751                 }
752                 else if (!decode_unqualified_name(output))
753                   _GLIBCPP_DEMANGLER_FAILURE;
754               }
755             }
756             if (qualifiers)
757               qualifiers->printing_suppressed();
758             break;
759           case unscoped_template_name:
760             decode_unscoped_name(output);
761             if (qualifiers)
762               qualifiers->printing_suppressed();
763             break;
764         }
765         M_pos = saved_pos;
766         --M_inside_substitution;
767         _GLIBCPP_DEMANGLER_RETURN;
768       }
769
770     // <template-param> ::= T_                  # first template parameter
771     //                  ::= T <parameter-2 non-negative number> _
772     //
773     template<typename Allocator>
774       bool
775       session<Allocator>::decode_template_param(string_type& output,
776           qualifier_list<Allocator>* qualifiers)
777       {
778         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_template_parameter");
779         if (current() != 'T')
780           _GLIBCPP_DEMANGLER_FAILURE;
781         unsigned int value = 0;
782         char c;
783         if ((c = next()) != '_')
784         {
785           while(std::isdigit(c))
786           {
787             value = value * 10 + c - '0';
788             c = next();
789           }
790           ++value;
791         }
792         if (eat_current() != '_')
793           _GLIBCPP_DEMANGLER_FAILURE;
794         value += M_template_arg_pos_offset;
795         if (value >= M_template_arg_pos.size())
796           _GLIBCPP_DEMANGLER_FAILURE;
797         int saved_pos = M_pos;
798         M_pos = M_template_arg_pos[value];
799         if (M_inside_type > 20)         // Rather than core dump.
800           _GLIBCPP_DEMANGLER_FAILURE;
801         ++M_inside_substitution;
802         if (current() == 'X')
803         {
804           eat_current();
805           decode_expression(output);
806         }
807         else if (current() == 'L')
808           decode_literal(output);
809         else
810           decode_type(output, qualifiers);
811         --M_inside_substitution;
812         M_pos = saved_pos;
813         _GLIBCPP_DEMANGLER_RETURN;
814       }
815
816     template<typename Allocator>
817       bool
818       session<Allocator>::decode_literal(string_type& output)
819       {
820         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_literal");
821         eat_current();  // Eat the 'L'.
822         if (current() == '_')
823         {
824           if (next() != 'Z')
825             _GLIBCPP_DEMANGLER_FAILURE;
826           eat_current();
827           if ((M_pos += decode_encoding(output, M_str + M_pos,
828                   M_maxpos - M_pos + 1)) < 0)
829             _GLIBCPP_DEMANGLER_FAILURE;
830         }
831         else
832         {
833           // Special cases
834           if (current() == 'b')
835           {
836             if (next() == '0')
837               output += "false";
838             else
839               output += "true";
840             eat_current();
841             _GLIBCPP_DEMANGLER_RETURN;
842           }
843           char c = current();
844 #ifdef _GLIBCPP_DEMANGLER_STYLE_LITERAL
845           if (c == 'i' || c == 'j' || c == 'l' ||
846               c == 'm' || c == 'x' || c == 'y')
847             eat_current();
848           else
849 #else
850 #ifndef _GLIBCPP_DEMANGLER_STYLE_LITERAL_INT
851           if (c == 'i')
852             eat_current();
853           else
854 #endif
855 #endif
856           {
857             output += '(';
858             if (!decode_type(output))
859               _GLIBCPP_DEMANGLER_FAILURE;
860             output += ')';
861           }
862           if (!decode_number(output))
863             _GLIBCPP_DEMANGLER_FAILURE;
864 #ifdef _GLIBCPP_DEMANGLER_STYLE_LITERAL
865           if (c == 'j' || c == 'm' || c == 'y')
866             output += 'u';
867           if (c == 'l' || c == 'm')
868             output += 'l';
869           if (c == 'x' || c == 'y')
870             output += "ll";
871 #endif
872         }
873         _GLIBCPP_DEMANGLER_RETURN;
874       }
875
876     // <operator-name> ::=
877     //   nw                             # new           
878     //   na                             # new[]
879     //   dl                             # delete        
880     //   da                             # delete[]      
881     //   ng                             # - (unary)     
882     //   ad                             # & (unary)     
883     //   de                             # * (unary)     
884     //   co                             # ~             
885     //   pl                             # +             
886     //   mi                             # -             
887     //   ml                             # *             
888     //   dv                             # /             
889     //   rm                             # %             
890     //   an                             # &             
891     //   or                             # |             
892     //   eo                             # ^             
893     //   aS                             # =             
894     //   pL                             # +=            
895     //   mI                             # -=            
896     //   mL                             # *=            
897     //   dV                             # /=            
898     //   rM                             # %=            
899     //   aN                             # &=            
900     //   oR                             # |=            
901     //   eO                             # ^=            
902     //   ls                             # <<            
903     //   rs                             # >>            
904     //   lS                             # <<=           
905     //   rS                             # >>=           
906     //   eq                             # ==            
907     //   ne                             # !=            
908     //   lt                             # <             
909     //   gt                             # >             
910     //   le                             # <=            
911     //   ge                             # >=            
912     //   nt                             # !             
913     //   aa                             # &&            
914     //   oo                             # ||            
915     //   pp                             # ++            
916     //   mm                             # --            
917     //   cm                             # ,             
918     //   pm                             # ->*           
919     //   pt                             # ->            
920     //   cl                             # ()            
921     //   ix                             # []            
922     //   qu                             # ?             
923     //   sz                             # sizeof        
924     //   sr                             # scope resolution (::), see below        
925     //   cv <type>                      # (cast)        
926     //   v <digit> <source-name>        # vendor extended operator
927     //
928     //
929     // Symbol operator codes exist of two characters, we need to find a
930     // quick hash so that their names can be looked up in a table.
931     //
932     // The puzzle :)
933     // Shift the rows so that there is at most one character per column.
934     //
935     // A perfect solution:
936     //                                              horizontal
937     //    .....................................     offset + 'a'
938     // a, ||a||d|||||||||n||||s||||||||||||||||||           2
939     // c, || || ||lm|o||| |||| ||||||||||||||||||          -3
940     // d, || a| |e  | ||l |||| |||v||||||||||||||           3
941     // e, ||  | |   o q|  |||| ||| ||||||||||||||          -4
942     // g, |e  | |      |  t||| ||| ||||||||||||||          -3
943     // i, |   | |      |   ||| ||| ||||||||||x|||    12
944     // l, |   | |      e   ||| ||| ||st|||||| |||           9
945     // m, |   | |          ||| ||| |i  lm|||| |||          18
946     // n, a   e g          ||t |w| |     |||| |||           0
947     // o,                  ||  | | |     ||o| r||          19
948     // p,                  lm  p | t     || |  ||           6
949     // q,                        |       || u  ||          14
950     // r,                        |       |m    |s          20
951     // s,                        r       z     |            6
952     //    .....................................
953     // ^            ^__ second character
954     // |___ first character
955     //
956
957     // Putting that solution in tables:
958
959     char const offset_table_c [1 + CHAR_MAX - CHAR_MIN ] =
960     {
961       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
962       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
963       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
964       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
965       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
966       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
967 #if (CHAR_MIN < 0)
968       // Add -CHAR_MIN extra zeroes (128):
969       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
970       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
971       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
972       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
973       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
974       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
975       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
976       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
977       //   a    b    c    d    e    f    g    h    i    j    k
978       0, -95,   0,-100, -94,-101,   0,-100,   0, -85,   0,   0,
979       //   l    m    n    o    p    q    r    s    t    u    v
980          -88, -79, -97, -78, -91, -83, -77, -91,   0,   0,   0,
981 #else
982       //   a    b    c    d    e    f    g    h    i    j    k
983       0, 161,   0, 156, 162, 155,   0, 156,   0, 171,   0,   0,
984       //   l    m    n    o    p    q    r    s    t    u    v
985          168, 177, 159, 178, 165, 173, 179, 165,   0,   0,   0,
986 #endif
987       // ... more zeros
988     };
989
990     struct entry_st
991     {
992       char const* opcode;
993       char const* symbol_name;
994       bool unary;
995     };
996
997     entry_st const symbol_name_table_c[39] = {
998       { "na",  "operator new[]", true },
999       { "ge",  "operator>=", false },
1000       { "aa",  "operator&&", false },
1001       { "da",  "operator delete[]", true },
1002       { "ne",  "operator!=", false },
1003       { "ad",  "operator&", true },     // unary
1004       { "ng",  "operator-", true },     // unary
1005       { "de",  "operator*", true },     // unary
1006       { "cl",  "operator()", true },
1007       { "cm",  "operator,", false },
1008       { "eo=", "operator^", false },
1009       { "co",  "operator~", false },
1010       { "eq",  "operator==", false },
1011       { "le",  "operator<=", false },
1012       { "dl",  "operator delete", true },
1013       { "an=", "operator&", false },
1014       { "gt",  "operator>", false },
1015       { "pl=", "operator+", false },
1016       { "pm",  "operator->*", false },
1017       { "nt",  "operator!", true },
1018       { "as=", "operator", false },
1019       { "pp",  "operator++", true },
1020       { "nw",  "operator new", true },
1021       { "sr",  "::", true },
1022       { "dv=", "operator/", false },
1023       { "pt",  "operator->", false },
1024       { "mi=", "operator-", false },
1025       { "ls=", "operator<<", false },
1026       { "lt",  "operator<", false },
1027       { "ml=", "operator*", false },
1028       { "mm",  "operator--", true },
1029       { "sz",  "sizeof", true },
1030       { "rm=", "operator%", false },
1031       { "oo",  "operator||", false },
1032       { "qu",  "operator?", false },
1033       { "ix",  "operator[]", true },
1034       { "or=", "operator|", false },
1035       { "", NULL, false },
1036       { "rs=", "operator>>", false }
1037     };
1038
1039     template<typename Allocator>
1040       bool
1041       session<Allocator>::decode_operator_name(string_type& output)
1042       {
1043         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_operator_name");
1044
1045         char opcode0 = current();
1046         char opcode1 = tolower(next());
1047
1048         register char hash;
1049         if ((hash = offset_table_c[opcode0 - CHAR_MIN]))
1050         {
1051           hash += opcode1;
1052           if (
1053 #if (CHAR_MIN < 0)
1054               hash >= 0 &&
1055 #endif
1056               hash < 39)
1057           {
1058             int index = static_cast<int>(static_cast<unsigned char>(hash));
1059             entry_st entry = symbol_name_table_c[index];
1060             if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1061                 && (opcode1 == current() || entry.opcode[2] == '='))
1062             {
1063               output += entry.symbol_name;
1064               if (opcode1 != current())
1065                 output += '=';
1066               eat_current();
1067               if (hash == 27 || hash == 28)
1068                 M_template_args_need_space = true;
1069               _GLIBCPP_DEMANGLER_RETURN;
1070             }
1071             else if (opcode0 == 'c' && opcode1 == 'v')
1072             {
1073               eat_current();
1074               output += "operator ";
1075               if (current() == 'T')
1076               {
1077                 // This is a templated cast operator.
1078                 // It must be of the form "cvT_I...E".
1079                 // Let M_template_arg_pos already point
1080                 // to the template argument.
1081                 M_template_arg_pos_offset = M_template_arg_pos.size();
1082                 M_template_arg_pos.push_back(M_pos + 3);
1083               }
1084               if (!decode_type(output))
1085                 _GLIBCPP_DEMANGLER_FAILURE;
1086               if (!M_inside_template_args)
1087                 M_name_is_conversion_operator = true;
1088               _GLIBCPP_DEMANGLER_RETURN;
1089             }
1090           }
1091         }
1092         _GLIBCPP_DEMANGLER_FAILURE;
1093       }
1094
1095     //
1096     // <expression> ::= <unary operator-name> <expression>
1097     //              ::= <binary operator-name> <expression> <expression>
1098     //              ::= <expr-primary>
1099     //
1100     // <expr-primary> ::= <template-param>              # Starts with a T
1101     //                ::= L <type> <value number> E     # literal
1102     //                ::= L <mangled-name> E            # external name
1103     //
1104     template<typename Allocator>
1105       bool
1106       session<Allocator>::decode_expression(string_type& output)
1107       {
1108         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_expression");
1109         if (current() == 'T')
1110         {
1111           if (!decode_template_param(output))
1112             _GLIBCPP_DEMANGLER_FAILURE;
1113           _GLIBCPP_DEMANGLER_RETURN;
1114         }
1115         else if (current() == 'L')
1116         {
1117           if (!decode_literal(output))
1118             _GLIBCPP_DEMANGLER_FAILURE;
1119           if (current() != 'E')
1120             _GLIBCPP_DEMANGLER_FAILURE;
1121           eat_current();
1122           _GLIBCPP_DEMANGLER_RETURN;
1123         }
1124         else
1125         {
1126           char opcode0 = current();
1127           char opcode1 = tolower(next());
1128
1129           register char hash;
1130           if ((hash = offset_table_c[opcode0 - CHAR_MIN]))
1131           {
1132             hash += opcode1;
1133             if (
1134 #if (CHAR_MIN < 0)
1135                 hash >= 0 &&
1136 #endif
1137                 hash < 39)
1138             {
1139               int index = static_cast<int>(static_cast<unsigned char>(hash));
1140               entry_st entry = symbol_name_table_c[index];
1141               if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
1142                   && (opcode1 == current() || entry.opcode[2] == '='))
1143               {
1144                 char const* p = entry.symbol_name;
1145                 if (!strncmp("operator", p, 8))
1146                   p += 8;
1147                 if (*p == ' ')
1148                   ++p;
1149                 if (entry.unary)
1150                   output += p;
1151                 bool is_eq = (opcode1 != current());
1152                 eat_current();
1153                 output += '(';
1154                 if (!decode_expression(output))
1155                   _GLIBCPP_DEMANGLER_FAILURE;
1156                 output += ')';
1157                 if (!entry.unary)
1158                 {
1159                   output += ' ';
1160                   output += p;
1161                   if (is_eq)
1162                     output += '=';
1163                   output += ' ';
1164                   output += '(';
1165                   if (!decode_expression(output))
1166                     _GLIBCPP_DEMANGLER_FAILURE;
1167                   output += ')';
1168                 }
1169                 _GLIBCPP_DEMANGLER_RETURN;
1170               }
1171             }
1172           }
1173         }
1174         _GLIBCPP_DEMANGLER_FAILURE;
1175       }
1176
1177     //
1178     // <template-args> ::= I <template-arg>+ E
1179     // <template-arg> ::= <type>                        # type or template
1180     //                ::= L <type> <value number> E     # literal
1181     //                ::= L_Z <encoding> E              # external name
1182     //                ::= X <expression> E              # expression
1183     template<typename Allocator>
1184       bool
1185       session<Allocator>::decode_template_args(string_type& output)
1186       {
1187         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_template_args");
1188         if (eat_current() != 'I')
1189           _GLIBCPP_DEMANGLER_FAILURE;
1190         int prev_size = M_template_arg_pos.size();
1191         ++M_inside_template_args;
1192         if (M_template_args_need_space)
1193         {
1194           output += ' ';
1195           M_template_args_need_space = false;
1196         }
1197         output += '<';
1198         for(;;)
1199         {
1200           if (M_inside_template_args == 1 && !M_inside_type)
1201             M_template_arg_pos.push_back(M_pos);
1202           if (current() == 'X')
1203           {
1204             eat_current();
1205             if (!decode_expression(output))
1206               _GLIBCPP_DEMANGLER_FAILURE;
1207             if (current() != 'E')
1208               _GLIBCPP_DEMANGLER_FAILURE;
1209             eat_current();
1210           }
1211           else if (current() == 'L')
1212           {
1213             if (!decode_literal(output))
1214               _GLIBCPP_DEMANGLER_FAILURE;
1215             if (current() != 'E')
1216               _GLIBCPP_DEMANGLER_FAILURE;
1217             eat_current();
1218           }
1219           else if (!decode_type(output))
1220             _GLIBCPP_DEMANGLER_FAILURE;
1221           if (current() == 'E')
1222             break;
1223           output += ", ";
1224         }
1225         eat_current();
1226         if (*(output.rbegin()) == '>')
1227           output += ' ';
1228         output += '>';
1229         --M_inside_template_args;
1230         if (!M_inside_template_args && !M_inside_type)
1231         {
1232           M_name_is_template = true;
1233           M_template_arg_pos_offset = prev_size;
1234         }
1235         _GLIBCPP_DEMANGLER_RETURN;
1236       }
1237
1238     // <bare-function-type> ::=
1239     //   <signature type>+              # types are parameter types
1240     //
1241     template<typename Allocator>
1242       bool
1243       session<Allocator>::decode_bare_function_type(string_type& output)
1244       {
1245         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_bare_function_type");
1246         if (M_saw_destructor)
1247         {
1248           if (eat_current() != 'v' || (current() != 'E' && current() != 0))
1249             _GLIBCPP_DEMANGLER_FAILURE;
1250           output += "()";
1251           M_saw_destructor = false;
1252           _GLIBCPP_DEMANGLER_RETURN;
1253         }
1254 #ifndef _GLIBCPP_DEMANGLER_STYLE_VOID
1255         if (current() == 'v')
1256         {
1257           eat_current();
1258           if (current() != 'E' && current() != 0)
1259             _GLIBCPP_DEMANGLER_FAILURE;
1260           output += "()";
1261           M_saw_destructor = false;
1262           _GLIBCPP_DEMANGLER_RETURN;
1263         }
1264 #endif
1265         output += '(';
1266         M_template_args_need_space = false;
1267         if (!decode_type(output))       // Must have at least one parameter.
1268           _GLIBCPP_DEMANGLER_FAILURE;
1269         while (current() != 'E' && current() != 0)
1270         {
1271           output += ", ";
1272           if (!decode_type(output))
1273             _GLIBCPP_DEMANGLER_FAILURE;
1274         }
1275         output += ')';
1276         _GLIBCPP_DEMANGLER_RETURN;
1277       }
1278
1279     // <type> ::=
1280     //   <builtin-type>         # Starts with a lower case character != r.
1281     //   <function-type>        # Starts with F
1282     //   <class-enum-type>      # Starts with N, S, C, D, Z, a digit or a lower
1283     //                          # case character.  Since a lower case character
1284     //                          # would be an operator name, that would be an
1285     //                          # error.  The S is a substitution or St
1286     //                          # (::std::).  A 'C' would be a constructor and
1287     //                          # thus also an error.
1288     //   <template-param>       # Starts with T
1289     //   <substitution>         # Starts with S
1290     //   <template-template-param> <template-args>  # Starts with T or S,
1291     //                                              # equivalent with the above.
1292     //
1293     //   <array-type>                   # Starts with A
1294     //   <pointer-to-member-type>       # Starts with M
1295     //   <CV-qualifiers> <type>         # Starts with r, V or K
1296     //   P <type>   # pointer-to        # Starts with P
1297     //   R <type>   # reference-to      # Starts with R
1298     //   C <type>   # complex (C 2000)  # Starts with C
1299     //   G <type>   # imaginary (C 2000)# Starts with G
1300     //   U <source-name> <type>         # vendor extended type qualifier,
1301     //                                  # starts with U
1302     //
1303     // <template-template-param> ::= <template-param>
1304     //                           ::= <substitution>
1305
1306     // My own analysis of how to decode qualifiers:
1307     //
1308     // F is a <function-type>, <T> is a <builtin-type>, <class-enum-type>,
1309     //   <template-param> or <template-template-param> <template-args>.
1310     // <Q> represents a series of qualifiers (not G or C).
1311     // <C> is an unqualified type.
1312     // <R> is a qualified type.
1313     // <B> is the bare-function-type without return type.
1314     // <I> is the array index.
1315     //                                          Substitutions:
1316     // <Q>M<C><Q2>F<R><B>E  ==> R (C::*Q)B Q2   "<C>", "F<R><B>E"
1317     //                                              (<R> and <B> recursive),
1318     //                                              "M<C><Q2>F<R><B>E".
1319     // <Q>F<R><B>E          ==> R (Q)B          "<R>", "<B>" (<B> recursive)
1320     //                                              and "F<R><B>E".
1321     //
1322     // Note that if <R> has postfix qualifiers (an array), then those
1323     // are added AFTER the (member) function type.  For example:
1324     // <Q>FPA<R><B>E ==> R (*(Q)B) [], where the PA added the prefix
1325     // "(*" and the postfix ") []".
1326     //
1327     // <Q>G<T>              ==> imaginary T Q   "<T>", "G<T>" (<T> recursive).
1328     // <Q>C<T>              ==> complex T Q     "<T>", "C<T>" (<T> recursive).
1329     // <Q><T>               ==> T Q             "<T>" (<T> recursive).
1330     //
1331     // where <Q> is any of:
1332     //
1333     // <Q>P             ==> *Q                          "P..."
1334     // <Q>R             ==> &Q                          "R..."
1335     // <Q>[K|V|r]+      ==> [ const| volatile| restrict]+Q      "KVr..."
1336     // <Q>U<S>          ==>  SQ                         "U<S>..."
1337     // <Q>M<C>          ==> C::*Q                       "M<C>..." (<C> recurs.)
1338     // A<I>             ==> [I]                         "A<I>..." (<I> recurs.)
1339     // <Q>A<I>          ==>  (Q) [I]                    "A<I>..." (<I> recurs.)
1340     //   Note that when <Q> ends on an A<I2> then the brackets are omitted:
1341     //   A<I2>A<I>        ==> [I2][I]
1342     //  
1343     // A <substitution> is handled with an input position switch during which
1344     // new substitutions are turned off.  Because recursive handling of types
1345     // (and therefore the order in which substitutions must be generated) must
1346     // be done left to right, but the generation of Q needs processing right to
1347     // left, substitutions per <type> are generated by reading the input left
1348     // to right and marking the starts of all substitutions only - implicitly
1349     // finishing them at the end of the type.  Then the output and real
1350     // substitutions are generated.
1351     //
1352     // The following comment was for the demangling of g++ version 3.0.x.  The
1353     // mangling (and I believe even the ABI description) have been fixed now
1354     // (as of g++ version 3.1). 
1355     //
1356     // g++ 3.0.x only:
1357     // The ABI specifies for pointer-to-member function types the format
1358     // <Q>M<T>F<R><B>E.  In other words, the qualifier <Q2> (see above) is
1359     // implicitely contained in <T> instead of explicitly part of the M format.
1360     // I am convinced that this is a bug in the ABI.  Unfortunately, this is
1361     // how we have to demangle things as it has a direct impact on the order
1362     // in which substitutions are stored.  This ill-formed design results in
1363     // rather ill-formed demangler code too however :/
1364     //
1365     // <Q2> is now explicitely part of the M format.
1366     // For some weird reason, g++ (3.2.1) does not add substitutions for
1367     // qualified member function pointers.  I think that is another bug.
1368     //
1369     template<typename Allocator>
1370       void
1371       qualifier_list<Allocator>::decode_qualifiers(
1372           string_type& prefix,
1373           string_type& postfix,
1374           bool member_function_pointer_qualifiers = false)
1375       {
1376         for(typename std::vector<qualifier<Allocator>, Allocator>::
1377             reverse_iterator iter = M_qualifier_starts.rbegin();
1378             iter != M_qualifier_starts.rend();)
1379         {
1380           if (!member_function_pointer_qualifiers
1381               && !(*iter).part_of_substitution())
1382           {
1383             int saved_inside_substitution = M_demangler.M_inside_substitution;
1384             M_demangler.M_inside_substitution = 0;
1385             M_demangler.add_substitution((*iter).get_start_pos(), type);
1386             M_demangler.M_inside_substitution = saved_inside_substitution;
1387           }
1388           char qualifier_char = (*iter).first_qualifier();
1389           for(; qualifier_char; qualifier_char = (*iter).next_qualifier())
1390           {
1391             switch(qualifier_char)
1392             {
1393               case 'P':
1394                 prefix += "*";
1395                 break;
1396               case 'R':
1397                 prefix += "&";
1398                 break;
1399               case 'K':
1400                 prefix += " const";
1401                 continue;
1402               case 'V':
1403                 prefix += " volatile";
1404                 continue;
1405               case 'r':
1406                 prefix += " restrict";
1407                 continue;
1408               case 'A':
1409               {
1410                 string_type index = (*iter).get_optional_type();
1411                 if (++iter != M_qualifier_starts.rend()
1412                     && (*iter).first_qualifier() != 'A')
1413                 {
1414                   prefix += " (";
1415                   postfix = ") [" + index + "]" + postfix;
1416                 }
1417                 else
1418                   postfix = "[" + index + "]" + postfix;
1419                 break;
1420               }
1421               case 'M':
1422                 prefix += " ";
1423                 prefix += (*iter).get_optional_type();
1424                 prefix += "::*";
1425                 break;
1426               case 'U':
1427                 prefix += " ";
1428                 prefix += (*iter).get_optional_type();
1429                 break;
1430               case 'G': // Only here so we added a substitution.
1431                 break;
1432             }
1433             break;
1434           }
1435           if (qualifier_char != 'A')
1436             ++iter;
1437         }
1438         M_printing_suppressed = false;
1439       }
1440
1441     //
1442     template<typename Allocator>
1443       bool
1444       session<Allocator>::decode_type_with_postfix(
1445           string_type& prefix, string_type& postfix,
1446           qualifier_list<Allocator>* qualifiers)
1447       {
1448         _GLIBCPP_DEMANGLER_DOUT_ENTERING2
1449             (qualifiers ? "decode_type" : "decode_type[with qualifiers]");
1450         ++M_inside_type;
1451         bool recursive_template_param_or_substitution_call;
1452         if (!(recursive_template_param_or_substitution_call = qualifiers))
1453             qualifiers = new qualifier_list<Allocator>(*this);
1454         // First eat all qualifiers.
1455         bool failure = false;
1456         for(;;)         // So we can use 'continue' to eat the next qualifier.
1457         {
1458           int start_pos = M_pos;
1459           switch(current())
1460           {
1461             case 'P':
1462               qualifiers->add_qualifier_start(pointer, start_pos,
1463                   M_inside_substitution);
1464               eat_current();
1465               continue;
1466             case 'R':
1467               qualifiers->add_qualifier_start(reference, start_pos,
1468                   M_inside_substitution);
1469               eat_current();
1470               continue;
1471             case 'K':
1472             case 'V':
1473             case 'r':
1474             {
1475               char c;
1476               int count = 0;
1477               do
1478               {
1479                 ++count;
1480                 c = next();
1481               }
1482               while(c == 'K' || c == 'V' || c == 'r');
1483               qualifiers->add_qualifier_start(cv_qualifier, start_pos, count,
1484                   M_inside_substitution);
1485               continue;
1486             }
1487             case 'U':
1488             {
1489               eat_current();
1490               string_type source_name;
1491               if (!decode_source_name(source_name))
1492               {
1493                 failure = true;
1494                 break;
1495               }
1496               qualifiers->add_qualifier_start(vendor_extension, start_pos,
1497                   source_name, M_inside_substitution);
1498               continue;
1499             }
1500             case 'A':
1501             {
1502               // <array-type> ::= A <positive dimension number> _ <element type>
1503               //              ::= A [<dimension expression>] _ <element type>
1504               //
1505               string_type index;
1506               int saved_pos;
1507               store(saved_pos);
1508               if (next() == 'n' || !decode_number(index))
1509               {
1510                 restore(saved_pos);
1511                 if (next() != '_' && !decode_expression(index))
1512                 {
1513                   failure = true;
1514                   break;
1515                 }
1516               }
1517               if (eat_current() != '_')
1518               {
1519                 failure = true;
1520                 break;
1521               }
1522               qualifiers->add_qualifier_start(array, start_pos, index,
1523                   M_inside_substitution);
1524               continue;
1525             }
1526             case 'M':
1527             {
1528               // <Q>M<C> or <Q>M<C><Q2>F<R><B>E
1529               eat_current();
1530               string_type class_type;
1531               if (!decode_type(class_type))             // Substitution: "<C>".
1532               {
1533                 failure = true;
1534                 break;
1535               }
1536               char c = current();
1537               if (c == 'F' || c == 'K' || c == 'V' || c == 'r')
1538                   // Must be CV-qualifiers and a member function pointer.
1539               {
1540                 // <Q>M<C><Q2>F<R><B>E  ==> R (C::*Q)B Q2
1541                 //     substitutions: "<C>", "F<R><B>E" (<R> and <B>
1542                 //                    recursive), "M<C><Q2>F<R><B>E".
1543                 int count = 0;
1544                 int Q2_start_pos = M_pos;
1545                 while(c == 'K' || c == 'V' || c == 'r')         // Decode <Q2>.
1546                 {
1547                   ++count;
1548                   c = next();
1549                 }
1550                 qualifier_list<Allocator> class_type_qualifiers(*this);
1551                 if (count)
1552                   class_type_qualifiers.
1553                       add_qualifier_start(cv_qualifier, Q2_start_pos,
1554                           count, M_inside_substitution);
1555                 string_type member_function_qualifiers;
1556                 // It is unclear why g++ doesn't add a substitution for
1557                 // "<Q2>F<R><B>E" as it should I think.
1558                 string_type member_function_qualifiers_postfix;
1559                 class_type_qualifiers.
1560                     decode_qualifiers(member_function_qualifiers,
1561                         member_function_qualifiers_postfix, true);
1562                 member_function_qualifiers +=
1563                     member_function_qualifiers_postfix;
1564                 // I don't think this substitution is actually ever used.
1565                 int function_pos = M_pos;
1566                 if (eat_current() != 'F')
1567                 {
1568                   failure = true;
1569                   break;
1570                 }
1571                 // Return type.
1572                 // Constructors, destructors and conversion operators don't
1573                 // have a return type, but seem to never get here.
1574                 if (!decode_type_with_postfix(prefix, postfix))
1575                     // substitution: <R> recursive
1576                 {
1577                   failure = true;
1578                   break;
1579                 }
1580                 prefix += " (";
1581                 prefix += class_type;
1582                 prefix += "::*";
1583                 string_type bare_function_type;
1584                 if (!decode_bare_function_type(bare_function_type)
1585                     || eat_current() != 'E')    // Substitution: <B> recursive.
1586                 {
1587                   failure = true;
1588                   break;
1589                 }
1590                 // substitution: "F<R><B>E".
1591                 add_substitution(function_pos, type);
1592                 // substitution: "M<C><Q2>F<R><B>E".
1593                 add_substitution(start_pos, type);
1594                 // substitution: all qualified types if any.
1595                 qualifiers->decode_qualifiers(prefix, postfix);
1596                 prefix += ")";
1597                 prefix += bare_function_type;
1598                 prefix += member_function_qualifiers;
1599                 goto decode_type_exit;
1600               }
1601               qualifiers->add_qualifier_start(pointer_to_member, start_pos,
1602                   class_type, M_inside_substitution);
1603               continue;
1604             }
1605             default:
1606               break;
1607           }
1608           break;
1609         }
1610         if (!failure)
1611         {
1612           // <Q>G<T>                    ==> imaginary T Q
1613           //     substitutions: "<T>", "G<T>" (<T> recursive).
1614           // <Q>C<T>                    ==> complex T Q
1615           //     substitutions: "<T>", "C<T>" (<T> recursive).
1616           if (current() == 'C' || current() == 'G')
1617           {
1618             prefix += current() == 'C' ? "complex " : "imaginary ";
1619             qualifiers->add_qualifier_start(complex_or_imaginary, M_pos,
1620                 M_inside_substitution);
1621             eat_current();
1622           }
1623           int start_pos = M_pos;
1624           switch(current())
1625           {
1626             case 'F':
1627             {
1628               // <Q>F<R><B>E            ==> R (Q)B
1629               //     substitution: "<R>", "<B>" (<B> recursive) and "F<R><B>E".
1630               eat_current();
1631               // Return type.
1632               if (!decode_type_with_postfix(prefix, postfix))
1633                   // Substitution: "<R>".
1634               {
1635                 failure = true;
1636                 break;
1637               }
1638               // Only array (pointer) types have a postfix.
1639               // In that case we don't want the space but
1640               // expect something like prefix is "int (*"
1641               // and postfix is ") [1]".
1642               if (postfix.size() == 0)
1643                 prefix += ' ';
1644               prefix += '(';
1645               string_type bare_function_type;
1646               if (!decode_bare_function_type(bare_function_type)
1647                   // substitution: "<B>" (<B> recursive).
1648                   || eat_current() != 'E')
1649               {
1650                 failure = true;
1651                 break;
1652               }
1653               add_substitution(start_pos, type);  // Substitution: "F<R><B>E".
1654               qualifiers->decode_qualifiers(prefix, postfix);
1655                   // substitution: all qualified types, if any.
1656               prefix += ")";
1657               prefix += bare_function_type;
1658               break;
1659             }
1660             case 'T':
1661               if (!decode_template_param(prefix, qualifiers))
1662               {
1663                 failure = true;
1664                 break;
1665               }
1666               if (current() == 'I')
1667               {
1668                 add_substitution(start_pos, template_template_param);
1669                     // substitution: "<template-template-param>".
1670                 if (!decode_template_args(prefix))
1671                 {
1672                   failure = true;
1673                   break;
1674                 }
1675               }
1676               if (!recursive_template_param_or_substitution_call
1677                   && qualifiers->suppressed())
1678               {
1679                 add_substitution(start_pos, type);
1680                     // substitution: "<template-param>" or
1681                     // "<template-template-param> <template-args>".
1682                 qualifiers->decode_qualifiers(prefix, postfix);
1683                     // substitution: all qualified types, if any.
1684               }
1685               break;
1686             case 'S':
1687               if (M_pos >= M_maxpos)
1688               {
1689                 failure = true;
1690                 break;
1691               }
1692               if (M_str[M_pos + 1] != 't')
1693               {
1694                 if (!decode_substitution(prefix, qualifiers))
1695                 {
1696                   failure = true;
1697                   break;
1698                 }
1699                 if (current() == 'I')
1700                 {
1701                   if (!decode_template_args(prefix))
1702                   {
1703                     failure = true;
1704                     break;
1705                   }
1706                   if (!recursive_template_param_or_substitution_call
1707                       && qualifiers->suppressed())
1708                     add_substitution(start_pos, type);
1709                         // Substitution:
1710                         //   "<template-template-param> <template-args>".
1711                 }
1712                 if (!recursive_template_param_or_substitution_call
1713                     && qualifiers->suppressed())
1714                   qualifiers->decode_qualifiers(prefix, postfix);
1715                       // Substitution: all qualified types, if any.
1716                 break;
1717               }
1718               /* Fall-through for St */
1719             case 'N':
1720             case 'Z':
1721             case '0':
1722             case '1':
1723             case '2':
1724             case '3':
1725             case '4':
1726             case '5':
1727             case '6':
1728             case '7':
1729             case '8':
1730             case '9':
1731               // <Q><T>                 ==> T Q
1732               //     substitutions: "<T>" (<T> recursive).
1733               if (!decode_class_enum_type(prefix))
1734               {
1735                 failure = true;
1736                 break;
1737               }
1738               if (!recursive_template_param_or_substitution_call)
1739               {
1740                 add_substitution(start_pos, type);
1741                     // substitution: "<class-enum-type>".
1742                 qualifiers->decode_qualifiers(prefix, postfix);
1743                     // substitution: all qualified types, if any.
1744               }
1745               else
1746                 qualifiers->printing_suppressed();
1747               break;
1748             default:
1749               // <Q><T>                 ==> T Q
1750               //     substitutions: "<T>" (<T> recursive).
1751               if (!decode_builtin_type(prefix))
1752               {
1753                 failure = true;
1754                 break;
1755               }
1756               // If decode_type was called from decode_template_param then we
1757               // need to suppress calling qualifiers here in order to get a
1758               // substitution added anyway (for the <template-param>).
1759               if (!recursive_template_param_or_substitution_call)
1760                 qualifiers->decode_qualifiers(prefix, postfix);
1761               else
1762                 qualifiers->printing_suppressed();
1763               break;
1764           }
1765         }
1766     decode_type_exit:
1767         --M_inside_type;
1768         if (!recursive_template_param_or_substitution_call)
1769           delete qualifiers;
1770         if (failure)
1771           _GLIBCPP_DEMANGLER_FAILURE;
1772         _GLIBCPP_DEMANGLER_RETURN2;
1773       }
1774
1775     // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
1776     //               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
1777     //
1778     // <prefix> ::= <prefix> <unqualified-name>
1779     //          ::= <template-prefix> <template-args>
1780     //          ::= # empty
1781     //          ::= <substitution>
1782     //
1783     // <template-prefix> ::= <prefix> <template unqualified-name>
1784     //                   ::= <substitution>
1785     //
1786     template<typename Allocator>
1787       bool
1788       session<Allocator>::decode_nested_name(string_type& output,
1789                                              string_type& qualifiers)
1790       {
1791         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_nested_name");
1792
1793         if (current() != 'N' || M_pos >= M_maxpos)
1794           _GLIBCPP_DEMANGLER_FAILURE;
1795
1796         // <CV-qualifiers> ::= [r] [V] [K]  # restrict (C99), volatile, const
1797         char const* qualifiers_start = &M_str[M_pos + 1];
1798         for (char c = next(); c == 'K' || c == 'V' || c == 'r'; c = next());
1799         for (char const* qualifier_ptr = &M_str[M_pos - 1];
1800              qualifier_ptr >= qualifiers_start; --qualifier_ptr)
1801           switch(*qualifier_ptr)
1802           {
1803             case 'K':
1804               qualifiers += " const";
1805               break;
1806             case 'V':
1807               qualifiers += " volatile";
1808               break;
1809             case 'r':
1810               qualifiers += " restrict";
1811               break;
1812           }
1813
1814         int number_of_prefixes = 0;
1815         int substitution_start = M_pos;
1816         for(;;)
1817         {
1818           ++number_of_prefixes;
1819           if (current() == 'S')
1820           {
1821             if (!decode_substitution(output))
1822               _GLIBCPP_DEMANGLER_FAILURE;
1823           }
1824           else if (current() == 'I')
1825           {
1826             if (!decode_template_args(output))
1827               _GLIBCPP_DEMANGLER_FAILURE;
1828             if (current() != 'E')
1829             {
1830               // substitution: "<template-prefix> <template-args>".
1831               add_substitution(substitution_start, nested_name_prefix,
1832                                number_of_prefixes);
1833             }
1834           }
1835           else
1836           {
1837             if (!decode_unqualified_name(output))
1838               _GLIBCPP_DEMANGLER_FAILURE;
1839             if (current() != 'E')
1840             {
1841               // substitution: "<prefix> <unqualified-name>" or
1842               // "<prefix> <template unqualified-name>".
1843               add_substitution(substitution_start,
1844                   (current() == 'I') ?  nested_name_template_prefix
1845                                      : nested_name_prefix,
1846                   number_of_prefixes);
1847             }
1848           }
1849           if (current() == 'E')
1850           {
1851             eat_current();
1852             _GLIBCPP_DEMANGLER_RETURN;
1853           }
1854           if (current() != 'I')
1855             output += "::";
1856           else if (M_template_args_need_space)
1857             output += ' ';
1858           M_template_args_need_space = false;
1859         }
1860         _GLIBCPP_DEMANGLER_FAILURE;
1861       }
1862
1863     // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
1864     //              := Z <function encoding> E s [<discriminator>]
1865     // <discriminator> := _ <non-negative number>
1866     //
1867     template<typename Allocator>
1868       bool
1869       session<Allocator>::decode_local_name(string_type& output)
1870       {
1871         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_local_name");
1872         if (current() != 'Z' || M_pos >= M_maxpos)
1873           _GLIBCPP_DEMANGLER_FAILURE;
1874         if ((M_pos += decode_encoding(output, M_str + M_pos + 1,
1875                 M_maxpos - M_pos) + 1) < 0 || eat_current() != 'E')
1876           _GLIBCPP_DEMANGLER_FAILURE;
1877         output += "::";
1878         if (current() == 's')
1879         {
1880           eat_current();
1881           output += "string literal";
1882         }
1883         else
1884         {
1885           string_type nested_name_qualifiers;
1886           if (!decode_name(output, nested_name_qualifiers))
1887             _GLIBCPP_DEMANGLER_FAILURE;
1888           output += nested_name_qualifiers;
1889         }
1890         string_type discriminator;
1891         if (current() == '_' && next() != 'n' && !decode_number(discriminator))
1892           _GLIBCPP_DEMANGLER_FAILURE;
1893         _GLIBCPP_DEMANGLER_RETURN;
1894       }
1895
1896     // <source-name> ::= <positive length number> <identifier>
1897     //
1898     template<typename Allocator>
1899       bool
1900       session<Allocator>::decode_source_name(string_type& output)
1901       {
1902         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_source_name");
1903         int length = current() - '0';
1904         if (length < 1 || length > 9)
1905           _GLIBCPP_DEMANGLER_FAILURE;
1906         while(std::isdigit(next()))
1907           length = 10 * length + current() - '0';
1908         char const* ptr = &M_str[M_pos];
1909         if (length > 11 && !strncmp(ptr, "_GLOBAL_", 8) && ptr[9] == 'N'
1910             && ptr[8] == ptr[10])
1911         {
1912           output += "(anonymous namespace)";
1913           if ((M_pos += length) > M_maxpos + 1)
1914             _GLIBCPP_DEMANGLER_FAILURE;
1915         }
1916         else
1917           while(length--)
1918           {
1919             if (current() == 0)
1920               _GLIBCPP_DEMANGLER_FAILURE;
1921             output += eat_current();
1922           }
1923         _GLIBCPP_DEMANGLER_RETURN;
1924       }
1925
1926     // <unqualified-name> ::= <operator-name>   # Starts with lower case.
1927     //                    ::= <ctor-dtor-name>  # Starts with 'C' or 'D'.
1928     //                    ::= <source-name>     # Starts with a digit.
1929     //
1930     template<typename Allocator>
1931       bool
1932       session<Allocator>::decode_unqualified_name(string_type& output)
1933       {
1934         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_unqualified_name");
1935         if (std::isdigit(current()))
1936         {
1937           if (!M_inside_template_args)
1938           {
1939             bool recursive_unqualified_name = (&M_function_name == &output);
1940             // This can be a recursive call when we are decoding
1941             // an <operator-name> that is a cast operator for a some
1942             // <unqualified-name>; for example "operator Foo()".
1943             // In that case this is thus not a ctor or dtor and we
1944             // are not interested in updating M_function_name.
1945             if (!recursive_unqualified_name)
1946               M_function_name.clear();
1947             M_name_is_template = false;
1948             M_name_is_cdtor = false;
1949             M_name_is_conversion_operator = false;
1950             if (!decode_source_name(M_function_name))
1951               _GLIBCPP_DEMANGLER_FAILURE;
1952             if (!recursive_unqualified_name)
1953               output += M_function_name;
1954           }
1955           else if (!decode_source_name(output))
1956             _GLIBCPP_DEMANGLER_FAILURE;
1957           _GLIBCPP_DEMANGLER_RETURN;
1958         }
1959         if (islower(current()))
1960         {
1961           if (!M_inside_template_args)
1962           {
1963             M_function_name.clear();
1964             M_name_is_template = false;
1965             M_name_is_cdtor = false;
1966             M_name_is_conversion_operator = false;
1967             if (!decode_operator_name(M_function_name))
1968               _GLIBCPP_DEMANGLER_FAILURE;
1969             output += M_function_name;
1970           }
1971           _GLIBCPP_DEMANGLER_RETURN;
1972         }
1973         if (current() == 'C' || current() == 'D')
1974         {
1975           if (M_inside_template_args)
1976             _GLIBCPP_DEMANGLER_FAILURE;
1977           // <ctor-dtor-name> ::=
1978           //   C1       # complete object (in-charge) constructor
1979           //   C2       # base object (not-in-charge) constructor
1980           //   C3       # complete object (in-charge) allocating constructor
1981           //   D0       # deleting (in-charge) destructor
1982           //   D1       # complete object (in-charge) destructor
1983           //   D2       # base object (not-in-charge) destructor
1984           //
1985           if (current() == 'C')
1986           {
1987             char c = next();
1988             if (c < '1' || c > '3')
1989               _GLIBCPP_DEMANGLER_FAILURE;
1990           }
1991           else
1992           {
1993             char c = next();
1994             if (c < '0' || c > '2')
1995               _GLIBCPP_DEMANGLER_FAILURE;
1996             output += '~';
1997             M_saw_destructor = true;
1998           }
1999           M_name_is_cdtor = true;
2000           eat_current();
2001           output += M_function_name;
2002           _GLIBCPP_DEMANGLER_RETURN;
2003         }
2004         _GLIBCPP_DEMANGLER_FAILURE;
2005       }
2006
2007     // <unscoped-name> ::=
2008     //   <unqualified-name>             # Starts not with an 'S'
2009     //   St <unqualified-name>  # ::std::
2010     //
2011     template<typename Allocator>
2012       bool
2013       session<Allocator>::decode_unscoped_name(string_type& output)
2014       {
2015         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_unscoped_name");
2016         if (current() == 'S')
2017         {
2018           if (next() != 't')
2019             _GLIBCPP_DEMANGLER_FAILURE;
2020           eat_current();
2021           output += "std::";
2022         }
2023         decode_unqualified_name(output);
2024         _GLIBCPP_DEMANGLER_RETURN;
2025       }
2026
2027     // <name> ::=
2028     //   <nested-name>                          # Starts with 'N'
2029     //   <unscoped-template-name> <template-args> # idem
2030     //   <local-name>                           # Starts with 'Z'
2031     //   <unscoped-name>                        # Starts with 'S', 'C', 'D',
2032     //                                          # a digit or a lower case
2033     //                                          # character.
2034     //
2035     // <unscoped-template-name> ::= <unscoped-name>
2036     //                          ::= <substitution>
2037     template<typename Allocator>
2038       bool
2039       session<Allocator>::decode_name(string_type& output,
2040                                       string_type& nested_name_qualifiers)
2041       {
2042         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_name");
2043         int substitution_start = M_pos;
2044         if (current() == 'S' && (M_pos >= M_maxpos || M_str[M_pos + 1] != 't'))
2045         {
2046           if (!decode_substitution(output))
2047             _GLIBCPP_DEMANGLER_FAILURE;
2048         }
2049         else if (current() == 'N')
2050         {
2051           decode_nested_name(output, nested_name_qualifiers);
2052           _GLIBCPP_DEMANGLER_RETURN;
2053         }
2054         else if (current() == 'Z')
2055         {
2056           decode_local_name(output);
2057           _GLIBCPP_DEMANGLER_RETURN;
2058         }
2059         else if (!decode_unscoped_name(output))
2060           _GLIBCPP_DEMANGLER_FAILURE;
2061         if (current() == 'I')
2062         {
2063           // Must have been an <unscoped-template-name>.
2064           add_substitution(substitution_start, unscoped_template_name);
2065           if (!decode_template_args(output))
2066             _GLIBCPP_DEMANGLER_FAILURE;
2067         }
2068         M_template_args_need_space = false;
2069         _GLIBCPP_DEMANGLER_RETURN;
2070       }
2071
2072     // <call-offset> ::= h <nv-offset> _
2073     //               ::= v <v-offset> _
2074     // <nv-offset>   ::= <offset number> 
2075     //     non-virtual base override
2076     //
2077     // <v-offset>    ::= <offset number> _ <virtual offset number>
2078     //     virtual base override, with vcall offset
2079     template<typename Allocator>
2080       bool
2081       session<Allocator>::decode_call_offset(string_type&
2082 #if _GLIBCPP_DEMANGLER_CWDEBUG
2083           output
2084 #endif
2085           )
2086       {
2087         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_call_offset");
2088         if (current() == 'h')
2089         {
2090           string_type dummy;
2091           eat_current();
2092           if (decode_number(dummy) && current() == '_')
2093           {
2094             eat_current();
2095             _GLIBCPP_DEMANGLER_RETURN;
2096           }
2097         }
2098         else if (current() == 'v')
2099         {
2100           string_type dummy;
2101           eat_current();
2102           if (decode_number(dummy) && current() == '_')
2103           {
2104             eat_current();
2105             if (decode_number(dummy) && current() == '_')
2106             {
2107               eat_current();
2108               _GLIBCPP_DEMANGLER_RETURN;
2109             }
2110           }
2111         }
2112         _GLIBCPP_DEMANGLER_FAILURE;
2113       }
2114
2115     //
2116     // <special-name> ::=
2117     //   TV <type>                      # virtual table
2118     //   TT <type>                      # VTT structure (construction
2119     //                                    vtable index).
2120     //   TI <type>                      # typeinfo structure
2121     //   TS <type>                      # typeinfo name (null-terminated
2122     //                                    byte string).
2123     //   GV <object name>               # Guard variable for one-time
2124     //                                    initialization of static objects in
2125     //                                    a local scope.
2126     //   T <call-offset> <base encoding># base is the nominal target function
2127     //                                    of thunk.
2128     //   Tc <call-offset> <call-offset> <base encoding> # base is the nominal
2129     //                                    target function of thunk; first
2130     //                                    call-offset is 'this' adjustment;
2131     //                                    second call-offset is result
2132     //                                    adjustment
2133     //
2134     template<typename Allocator>
2135       bool
2136       session<Allocator>::decode_special_name(string_type& output)
2137       {
2138         _GLIBCPP_DEMANGLER_DOUT_ENTERING("decode_special_name");
2139         if (current() == 'G')
2140         {
2141           if (next() != 'V')
2142             _GLIBCPP_DEMANGLER_FAILURE;
2143           output += "guard variable for ";
2144           string_type nested_name_qualifiers;
2145           eat_current();
2146           if (!decode_name(output, nested_name_qualifiers))
2147             _GLIBCPP_DEMANGLER_FAILURE;
2148           output += nested_name_qualifiers;
2149           _GLIBCPP_DEMANGLER_RETURN;
2150         }
2151         else if (current() != 'T')
2152           _GLIBCPP_DEMANGLER_FAILURE;
2153         switch(next())
2154         {
2155           case 'V':
2156             output += "vtable for ";
2157             eat_current();
2158             decode_type(output);
2159             _GLIBCPP_DEMANGLER_RETURN;
2160           case 'T':
2161             output += "VTT for ";
2162             eat_current();
2163             decode_type(output);
2164             _GLIBCPP_DEMANGLER_RETURN;
2165           case 'I':
2166             output += "typeinfo for ";
2167             eat_current();
2168             decode_type(output);
2169             _GLIBCPP_DEMANGLER_RETURN;
2170           case 'S':
2171             output += "typeinfo name for ";
2172             eat_current();
2173             decode_type(output);
2174             _GLIBCPP_DEMANGLER_RETURN;
2175           case 'c':
2176             output += "covariant return thunk to ";
2177             if (!decode_call_offset(output)
2178                 || !decode_call_offset(output)
2179                 || (M_pos += decode_encoding(output, M_str + M_pos,
2180                     M_maxpos - M_pos + 1)) < 0)
2181               _GLIBCPP_DEMANGLER_FAILURE;
2182             _GLIBCPP_DEMANGLER_RETURN;
2183           case 'C':             // GNU extension?
2184           {
2185             string_type first;
2186             output += "construction vtable for ";
2187             eat_current();
2188             if (!decode_type(first))
2189               _GLIBCPP_DEMANGLER_FAILURE;
2190             while(std::isdigit(current()))
2191               eat_current();
2192             if (eat_current() != '_')
2193               _GLIBCPP_DEMANGLER_FAILURE;
2194             if (!decode_type(output))
2195               _GLIBCPP_DEMANGLER_FAILURE;
2196             output += "-in-";
2197             output += first;
2198             _GLIBCPP_DEMANGLER_RETURN;
2199           }
2200           default:
2201             if (current() == 'v')
2202               output += "virtual thunk to ";
2203             else
2204               output += "non-virtual thunk to ";
2205             if (!decode_call_offset(output)
2206                 || (M_pos += decode_encoding(output, M_str + M_pos,
2207                     M_maxpos - M_pos + 1)) < 0)
2208               _GLIBCPP_DEMANGLER_FAILURE;
2209             _GLIBCPP_DEMANGLER_RETURN;
2210         }
2211       }
2212
2213     // <encoding> ::=
2214     //   <function name> <bare-function-type>   # Starts with 'C', 'D', 'N',
2215     //                                            'S', a digit or a lower case
2216     //                                            character.
2217     //   <data name>                            # Idem.
2218     //   <special-name>                         # Starts with 'T' or 'G'.
2219     template<typename Allocator>
2220       int
2221       session<Allocator>::decode_encoding(string_type& output,
2222                                           char const* in,
2223                                           int len)
2224       {
2225 #if _GLIBCPP_DEMANGLER_CWDEBUG
2226         _GLIBCPP_DEMANGLER_DOUT(dc::demangler,
2227             "Output thus far: \"" << output << '"');
2228         string_type input(in, len > 0x40000000 ? strlen(in) : len);
2229         _GLIBCPP_DEMANGLER_DOUT(
2230             dc::demangler, "Entering decode_encoding(\"" << input << "\")");
2231 #endif
2232         if (len <= 0)
2233           return INT_MIN;
2234         session<Allocator> demangler_session(in, len);
2235         string_type nested_name_qualifiers;
2236         int saved_pos;
2237         demangler_session.store(saved_pos);
2238         if (demangler_session.decode_special_name(output))
2239           return demangler_session.M_pos;
2240         demangler_session.restore(saved_pos);
2241         string_type name;
2242         if (!demangler_session.decode_name(name, nested_name_qualifiers))
2243           return INT_MIN;
2244         if (demangler_session.current() == 0
2245             || demangler_session.current() == 'E')
2246         {
2247           output += name;
2248           output += nested_name_qualifiers;
2249           return demangler_session.M_pos;
2250         }
2251         // Must have been a <function name>.
2252         if (demangler_session.M_name_is_template
2253             && !(demangler_session.M_name_is_cdtor
2254                  || demangler_session.M_name_is_conversion_operator))
2255         {
2256           if (!demangler_session.decode_type(output))
2257               // Return type of function
2258             return INT_MIN;
2259           output += ' ';
2260         }
2261         output += name;
2262         if (!demangler_session.decode_bare_function_type(output))
2263           return INT_MIN;
2264         output += nested_name_qualifiers;
2265         return demangler_session.M_pos;
2266       }
2267
2268     } // namespace demangler
2269
2270   // Public interface
2271   template<typename Allocator>
2272     struct demangle
2273     {
2274       typedef Allocator allocator_type;
2275       typedef std::basic_string<char, std::char_traits<char>, Allocator> 
2276           string_type;
2277       static string_type symbol(char const* in);
2278       static string_type type(char const* in);
2279     };
2280
2281   // demangle::symbol()
2282   //
2283   // Demangle `input' which should be a mangled function name as for
2284   // instance returned by nm(1).
2285   template<typename Allocator>
2286     std::basic_string<char, std::char_traits<char>, Allocator>
2287     demangle<Allocator>::symbol(char const* input)
2288     {
2289       // <mangled-name> ::= _Z <encoding>
2290       // <mangled-name> ::= _GLOBAL_ _<type>_ _Z <encoding>             
2291       //                    <type> can be I or D (GNU extension)
2292       typedef demangler::session<Allocator> demangler_type;
2293       string_type result;
2294       bool failure = (input[0] != '_');
2295
2296       if (!failure)
2297       {
2298         if (input[1] == 'G')
2299         {
2300           if (!strncmp(input, "_GLOBAL__", 9)
2301               && (input[9] == 'D' || input[9] == 'I')
2302               && input[10] == '_' && input[11] == '_' && input[12] == 'Z')
2303           {
2304             if (input[9] == 'D')
2305               result.assign("global destructors keyed to ", 28);
2306             else
2307               result.assign("global constructors keyed to ", 29);
2308             int cnt = demangler_type::decode_encoding(result, input + 13,
2309                                                       INT_MAX);
2310             if (cnt < 0 || input[cnt + 13] != 0)
2311               failure = true;
2312           }
2313           else
2314             failure = true;
2315         }
2316         else if (input[1] == 'Z')
2317         {
2318           int cnt = demangler_type::decode_encoding(result, input + 2,
2319                                                     INT_MAX);
2320           if (cnt < 0 || input[cnt + 2] != 0)
2321             failure = true;
2322         }
2323         else
2324           failure = true;
2325       }
2326
2327       // Failure to demangle, return the mangled name.
2328       if (failure)
2329         result.assign(input, strlen(input));
2330
2331       return result;
2332     }
2333
2334   // demangle::type()
2335   // Demangle `input' which must be a zero terminated mangled type
2336   // name as for instance returned by std::type_info::name().
2337   template<typename Allocator>
2338     std::basic_string<char, std::char_traits<char>, Allocator> 
2339     demangle<Allocator>::type(char const* input)
2340     {
2341       std::basic_string<char, std::char_traits<char>, Allocator> result;
2342       if (input == NULL)
2343         result = "(null)";
2344       else
2345       {
2346         demangler::session<Allocator> demangler_session(input, INT_MAX);
2347         if (!demangler_session.decode_type(result)
2348             || demangler_session.remaining_input_characters())
2349         {
2350           // Failure to demangle, return the mangled name.
2351           result = input;                               
2352         }
2353       }
2354       return result;
2355     }
2356
2357 } // namespace __gnu_cxx
2358
2359 #endif // __DEMANGLE_H