home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 April / PCWorld_2008-04_cd.bin / temacd / devc++ / devcpp-4.9.9.2_setup.exe / demangle.h < prev    next >
C/C++ Source or Header  |  2005-01-29  |  84KB  |  2,790 lines

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