📄 demangle.h
字号:
// C++ IA64 / g++ v3 demangler -*- C++ -*-// Copyright (C) 2003, 2004 Free Software Foundation, Inc.// Written by Carlo Wood <carlo@alinoe.com>//// This file is part of the GNU ISO C++ Library. This library is free// software; you can redistribute it and/or modify it under the// terms of the GNU General Public License as published by the// Free Software Foundation; either version 2, or (at your option)// any later version.// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License along// with this library; see the file COPYING. If not, write to the Free// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,// USA.// As a special exception, you may use this file as part of a free software// library without restriction. Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License. This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.// This file implements demangling of "C++ ABI for Itanium"-mangled symbol// and type names as described in Revision 1.73 of the C++ ABI as can be found// at http://www.codesourcery.com/cxx-abi/abi.html#mangling#ifndef _DEMANGLER_H#define _DEMANGLER_H 1#include <vector>#include <string>#include <ext/new_allocator.h>#ifndef _GLIBCXX_DEMANGLER_DEBUG#define _GLIBCXX_DEMANGLER_CWDEBUG 0#define _GLIBCXX_DEMANGLER_DEBUG(x)#define _GLIBCXX_DEMANGLER_DOUT(cntrl, data)#define _GLIBCXX_DEMANGLER_DOUT_ENTERING(x)#define _GLIBCXX_DEMANGLER_DOUT_ENTERING2(x)#define _GLIBCXX_DEMANGLER_DOUT_ENTERING3(x)#define _GLIBCXX_DEMANGLER_RETURN return M_result#define _GLIBCXX_DEMANGLER_RETURN2 return M_result#define _GLIBCXX_DEMANGLER_RETURN3#define _GLIBCXX_DEMANGLER_FAILURE \ do { M_result = false; return false; } while(0)#else#define _GLIBCXX_DEMANGLER_CWDEBUG 1#endifnamespace __gnu_cxx{ namespace demangler { enum substitution_nt { type, template_template_param, nested_name_prefix, nested_name_template_prefix, unscoped_template_name }; struct substitution_st { int M_start_pos; substitution_nt M_type; int M_number_of_prefixes; substitution_st(int start_pos, substitution_nt type, int number_of_prefixes) : M_start_pos(start_pos), M_type(type), M_number_of_prefixes(number_of_prefixes) { } }; enum simple_qualifier_nt { complex_or_imaginary = 'G', pointer = 'P', reference = 'R' }; enum cv_qualifier_nt { cv_qualifier = 'K' }; enum param_qualifier_nt { vendor_extension = 'U', array = 'A', pointer_to_member = 'M' }; template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> > class qualifier; template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> > class qualifier_list; template<typename Tp, typename Allocator = __gnu_cxx::new_allocator<Tp> > class session; template<typename Tp, typename Allocator> class qualifier { typedef typename Allocator::template rebind<char>::other char_Allocator; typedef std::basic_string<char, std::char_traits<char>, char_Allocator> string_type; private: char M_qualifier1; char M_qualifier2; char M_qualifier3; mutable unsigned char M_cnt; string_type M_optional_type; int M_start_pos; bool M_part_of_substitution; public: qualifier(int start_pos, simple_qualifier_nt simple_qualifier, int inside_substitution) : M_qualifier1(simple_qualifier), M_start_pos(start_pos), M_part_of_substitution(inside_substitution) { } qualifier(int start_pos, cv_qualifier_nt, char const* start, int count, int inside_substitution) : M_qualifier1(start[0]), M_qualifier2((count > 1) ? start[1] : '\0'), M_qualifier3((count > 2) ? start[2] : '\0'), M_start_pos(start_pos), M_part_of_substitution(inside_substitution) { } qualifier(int start_pos, param_qualifier_nt param_qualifier, string_type optional_type, int inside_substitution) : M_qualifier1(param_qualifier), M_optional_type(optional_type), M_start_pos(start_pos), M_part_of_substitution(inside_substitution) { } int get_start_pos(void) const { return M_start_pos; } char first_qualifier(void) const { M_cnt = 1; return M_qualifier1; } char next_qualifier(void) const { return (++M_cnt == 2) ? M_qualifier2 : ((M_cnt == 3) ? M_qualifier3 : 0); } string_type const& get_optional_type(void) const { return M_optional_type; } bool part_of_substitution(void) const { return M_part_of_substitution; }#if _GLIBCXX_DEMANGLER_CWDEBUG friend std::ostream& operator<<(std::ostream& os, qualifier const& qual) { os << (char)qual.M_qualifier1; if (qual.M_qualifier1 == vendor_extension || qual.M_qualifier1 == array || qual.M_qualifier1 == pointer_to_member) os << " [" << qual.M_optional_type << ']'; else if (qual.M_qualifier1 == 'K' || qual.M_qualifier1 == 'V' || qual.M_qualifier1 == 'r') { if (qual.M_qualifier2) { os << (char)qual.M_qualifier2; if (qual.M_qualifier3) os << (char)qual.M_qualifier3; } } return os; }#endif }; template<typename Tp, typename Allocator> class qualifier_list { typedef typename Allocator::template rebind<char>::other char_Allocator; typedef std::basic_string<char, std::char_traits<char>, char_Allocator> string_type; private: mutable bool M_printing_suppressed; typedef qualifier<Tp, Allocator> qual; typedef typename Allocator::template rebind<qual>::other qual_Allocator; typedef std::vector<qual, qual_Allocator> qual_vector; qual_vector M_qualifier_starts; session<Tp, Allocator>& M_demangler; void decode_KVrA(string_type& prefix, string_type& postfix, int cvq, typename qual_vector:: const_reverse_iterator const& iter_array) const; public: qualifier_list(session<Tp, Allocator>& demangler_obj) : M_printing_suppressed(false), M_demangler(demangler_obj) { } void add_qualifier_start(simple_qualifier_nt simple_qualifier, int start_pos, int inside_substitution) { M_qualifier_starts. push_back(qualifier<Tp, Allocator>(start_pos, simple_qualifier, inside_substitution)); } void add_qualifier_start(cv_qualifier_nt cv_qualifier, int start_pos, int count, int inside_substitution) { M_qualifier_starts. push_back(qualifier<Tp, Allocator>(start_pos, cv_qualifier, &M_demangler.M_str[start_pos], count, inside_substitution)); } void add_qualifier_start(param_qualifier_nt param_qualifier, int start_pos, string_type optional_type, int inside_substitution) { M_qualifier_starts. push_back(qualifier<Tp, Allocator>(start_pos, param_qualifier, optional_type, inside_substitution)); } void decode_qualifiers(string_type& prefix, string_type& postfix, bool member_function_pointer_qualifiers) const; bool suppressed(void) const { return M_printing_suppressed; } void printing_suppressed(void) { M_printing_suppressed = true; } size_t size(void) const { return M_qualifier_starts.size(); }#if _GLIBCXX_DEMANGLER_CWDEBUG friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list) { typename qual_vector::const_iterator iter = list.M_qualifier_starts.begin(); if (iter != list.M_qualifier_starts.end()) { os << "{ " << *iter; while (++iter != list.M_qualifier_starts.end()) os << ", " << *iter; os << " }"; } else os << "{ }"; return os; }#endif }; struct implementation_details { private: unsigned int M_style; public: // The following flags change the behaviour of the demangler. The // default behaviour is that none of these flags is set. static unsigned int const style_void = 1; // Default behaviour: int f() // Use (void) instead of (): int f(void) static unsigned int const style_literal = 2; // Default behaviour: (long)13, // (unsigned long long)19 // Use extensions 'u', 'l' and 'll' for integral // literals (as in template arguments): 13l, 19ull static unsigned int const style_literal_int = 4; // Default behaviour: 4 // Use also an explicit // cast for int in literals: (int)4 static unsigned int const style_compact_expr_ops = 8; // Default behaviour: (i) < (3), sizeof (int) // Don't output spaces around // operators in expressions: (i)<(3), sizeof(int) static unsigned int const style_sizeof_typename = 16; // Default behaviour: sizeof (X::t) // Put 'typename' infront of <nested-name> // types inside a 'sizeof': sizeof (typename X::t) public: implementation_details(unsigned int style_flags = 0) : M_style(style_flags) { } virtual ~implementation_details() { } bool get_style_void(void) const { return (M_style & style_void); } bool get_style_literal(void) const { return (M_style & style_literal); } bool get_style_literal_int(void) const { return (M_style & style_literal_int); } bool get_style_compact_expr_ops(void) const { return (M_style & style_compact_expr_ops); } bool get_style_sizeof_typename(void) const { return (M_style & style_sizeof_typename); } // This can be overridden by user implementations. virtual bool decode_real(char* /* output */, unsigned long* /* input */, size_t /* size_of_real */) const { return false; } }; template<typename Tp, typename Allocator> class session { public: friend class qualifier_list<Tp, Allocator>; typedef typename Allocator::template rebind<char>::other char_Allocator; typedef std::basic_string<char, std::char_traits<char>, char_Allocator> string_type; private: char const* M_str; int M_pos; int M_maxpos; bool M_result; int M_inside_template_args; int M_inside_type; int M_inside_substitution; bool M_saw_destructor; bool M_name_is_cdtor; bool M_name_is_template; bool M_name_is_conversion_operator; bool M_template_args_need_space; string_type M_function_name; typedef typename Allocator::template rebind<int>::other int_Allocator; typedef typename Allocator::template rebind<substitution_st>::other subst_Allocator; std::vector<int, int_Allocator> M_template_arg_pos; int M_template_arg_pos_offset; std::vector<substitution_st, subst_Allocator> M_substitutions_pos; implementation_details const& M_implementation_details; typedef typename Allocator::template rebind<qualifier_list<Allocator> >::other qualifier_list_Allocator; qualifier_list_Allocator M_qualifier_list_alloc;#if _GLIBCXX_DEMANGLER_CWDEBUG bool M_inside_add_substitution;#endif public: explicit session(char const* in, int len, implementation_details const& id = implementation_details()) : M_str(in), M_pos(0), M_maxpos(len - 1), M_result(true), M_inside_template_args(0), M_inside_type(0), M_inside_substitution(0), M_saw_destructor(false), M_name_is_cdtor(false), M_name_is_template(false), M_name_is_conversion_operator(false), M_template_args_need_space(false), M_template_arg_pos_offset(0), M_implementation_details(id)#if _GLIBCXX_DEMANGLER_CWDEBUG , M_inside_add_substitution(false)#endif { } static int decode_encoding(string_type& output, char const* input, int len, implementation_details const& id = implementation_details()); bool decode_type(string_type& output, qualifier_list<Tp, Allocator>* qualifiers = NULL) { string_type postfix; bool res = decode_type_with_postfix(output, postfix, qualifiers); output += postfix; return res; } bool remaining_input_characters(void) const { return current() != 0; } private: char current(void) const { return (M_pos > M_maxpos) ? 0 : M_str[M_pos]; } char next_peek(void) const { return (M_pos >= M_maxpos) ? 0 : M_str[M_pos + 1]; } char next(void) { return (M_pos >= M_maxpos) ? 0 : M_str[++M_pos]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -