source: svn/newcon3bcm2_21bu/toolchain/include/c++/3.4.2/ext/demangle.h @ 22

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