?? 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
#endif
namespace __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;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -