?? demangle.h
字號:
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]; }
char
eat_current(void)
{ return (M_pos > M_maxpos) ? 0 : M_str[M_pos++]; }
void
store(int& saved_pos)
{ saved_pos = M_pos; }
void
restore(int saved_pos)
{ M_pos = saved_pos; M_result = true; }
void
add_substitution(int start_pos,
substitution_nt sub_type,
int number_of_prefixes);
bool decode_type_with_postfix(string_type& prefix,
string_type& postfix, qualifier_list<Tp, Allocator>* qualifiers = NULL);
bool decode_bare_function_type(string_type& output);
bool decode_builtin_type(string_type& output);
bool decode_call_offset(string_type& output);
bool decode_class_enum_type(string_type& output);
bool decode_expression(string_type& output);
bool decode_literal(string_type& output);
bool decode_local_name(string_type& output);
bool decode_name(string_type& output,
string_type& nested_name_qualifiers);
bool decode_nested_name(string_type& output,
string_type& qualifiers);
bool decode_number(string_type& output);
bool decode_operator_name(string_type& output);
bool decode_source_name(string_type& output);
bool decode_substitution(string_type& output,
qualifier_list<Tp, Allocator>* qualifiers = NULL);
bool decode_template_args(string_type& output);
bool decode_template_param(string_type& output,
qualifier_list<Tp, Allocator>* qualifiers = NULL);
bool decode_unqualified_name(string_type& output);
bool decode_unscoped_name(string_type& output);
bool decode_non_negative_decimal_integer(string_type& output);
bool decode_special_name(string_type& output);
bool decode_real(string_type& output, size_t size_of_real);
};
template<typename Tp, typename Allocator>
#if !_GLIBCXX_DEMANGLER_CWDEBUG
inline
#endif
void
session<Tp, Allocator>::add_substitution(int start_pos,
substitution_nt sub_type,
int number_of_prefixes = 0)
{
if (!M_inside_substitution)
{
#if _GLIBCXX_DEMANGLER_CWDEBUG
if (M_inside_add_substitution)
return;
#endif
M_substitutions_pos.
push_back(substitution_st(start_pos,
sub_type, number_of_prefixes));
#if _GLIBCXX_DEMANGLER_CWDEBUG
if (!DEBUGCHANNELS::dc::demangler.is_on())
return;
string_type substitution_name("S");
int n = M_substitutions_pos.size() - 1;
if (n > 0)
substitution_name += (n <= 10) ? (char)(n + '0' - 1)
: (char)(n + 'A' - 11);
substitution_name += '_';
string_type subst;
int saved_pos = M_pos;
M_pos = start_pos;
M_inside_add_substitution = true;
_GLIBCXX_DEMANGLER_DEBUG( dc::demangler.off() );
switch(sub_type)
{
case type:
decode_type(subst);
break;
case template_template_param:
decode_template_param(subst);
break;
case nested_name_prefix:
case nested_name_template_prefix:
for (int cnt = number_of_prefixes; cnt > 0; --cnt)
{
if (current() == 'I')
{
subst += ' ';
decode_template_args(subst);
}
else
{
if (cnt < number_of_prefixes)
subst += "::";
if (current() == 'S')
decode_substitution(subst);
else if (current() == 'T')
decode_template_param(subst);
else
decode_unqualified_name(subst);
}
}
break;
case unscoped_template_name:
decode_unscoped_name(subst);
break;
}
M_pos = saved_pos;
_GLIBCXX_DEMANGLER_DEBUG( dc::demangler.on() );
_GLIBCXX_DEMANGLER_DOUT(dc::demangler,
"Adding substitution " << substitution_name
<< " : " << subst
<< " (from " << location_ct((char*)__builtin_return_address(0)
+ builtin_return_address_offset)
<< " <- " << location_ct((char*)__builtin_return_address(1)
+ builtin_return_address_offset)
<< " <- " << location_ct((char*)__builtin_return_address(2)
+ builtin_return_address_offset)
<< ").");
M_inside_add_substitution = false;
#endif
}
}
// We don't want to depend on locale (or include <cctype> for that matter).
// We also don't want to use "safe-ctype.h" because that headerfile is not
// available to the users.
inline bool isdigit(char c) { return c >= '0' && c <= '9'; }
inline bool islower(char c) { return c >= 'a' && c <= 'z'; }
inline bool isupper(char c) { return c >= 'A' && c <= 'Z'; }
inline char tolower(char c) { return isupper(c) ? c - 'A' + 'a' : c; }
//
// <non-negative decimal integer> ::= 0
// ::= 1|2|3|4|5|6|7|8|9 [<digit>+]
// <digit> ::= 0|1|2|3|4|5|6|7|8|9
//
template<typename Tp, typename Allocator>
bool
session<Tp, Allocator>::
decode_non_negative_decimal_integer(string_type& output)
{
char c = current();
if (c == '0')
{
output += '0';
eat_current();
}
else if (!isdigit(c))
M_result = false;
else
{
do
{
output += c;
}
while (isdigit((c = next())));
}
return M_result;
}
// <number> ::= [n] <non-negative decimal integer>
//
template<typename Tp, typename Allocator>
bool
session<Tp, Allocator>::decode_number(string_type& output)
{
_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_number");
if (current() != 'n')
decode_non_negative_decimal_integer(output);
else
{
output += '-';
eat_current();
decode_non_negative_decimal_integer(output);
}
_GLIBCXX_DEMANGLER_RETURN;
}
// <builtin-type> ::= v # void
// ::= w # wchar_t
// ::= b # bool
// ::= c # char
// ::= a # signed char
// ::= h # unsigned char
// ::= s # short
// ::= t # unsigned short
// ::= i # int
// ::= j # unsigned int
// ::= l # long
// ::= m # unsigned long
// ::= x # long long, __int64
// ::= y # unsigned long long, __int64
// ::= n # __int128
// ::= o # unsigned __int128
// ::= f # float
// ::= d # double
// ::= e # long double, __float80
// ::= g # __float128
// ::= z # ellipsis
// ::= u <source-name> # vendor extended type
//
char const* const builtin_type_c[26] =
{
"signed char", // a
"bool", // b
"char", // c
"double", // d
"long double", // e
"float", // f
"__float128", // g
"unsigned char", // h
"int", // i
"unsigned int", // j
NULL, // k
"long", // l
"unsigned long", // m
"__int128", // n
"unsigned __int128", // o
NULL, // p
NULL, // q
NULL, // r
"short", // s
"unsigned short", // t
NULL, // u
"void", // v
"wchar_t", // w
"long long", // x
"unsigned long long", // y
"..." // z
};
//
template<typename Tp, typename Allocator>
bool
session<Tp, Allocator>::decode_builtin_type(string_type& output)
{
_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_builtin_type");
char const* bt;
if (!islower(current()) || !(bt = builtin_type_c[current() - 'a']))
_GLIBCXX_DEMANGLER_FAILURE;
output += bt;
eat_current();
_GLIBCXX_DEMANGLER_RETURN;
}
// <class-enum-type> ::= <name>
//
template<typename Tp, typename Allocator>
bool
session<Tp, Allocator>::decode_class_enum_type(string_type& output)
{
_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_class_enum_type");
string_type nested_name_qualifiers;
if (!decode_name(output, nested_name_qualifiers))
_GLIBCXX_DEMANGLER_FAILURE;
output += nested_name_qualifiers;
_GLIBCXX_DEMANGLER_RETURN;
}
// <substitution> ::=
// S <seq-id> _
// S_
// St # ::std::
// Sa # ::std::allocator
// Sb # ::std::basic_string
// Ss # ::std::basic_string<char, std::char_traits<char>,
// std::allocator<char> >
// Si # ::std::basic_istream<char, std::char_traits<char> >
// So # ::std::basic_ostream<char, std::char_traits<char> >
// Sd # ::std::basic_iostream<char, std::char_traits<char> >
//
// <seq-id> ::=
// 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
// [<seq-id>] # Base 36 number
//
template<typename Tp, typename Allocator>
bool
session<Tp, Allocator>::decode_substitution(string_type& output,
qualifier_list<Tp, Allocator>* qualifiers)
{
_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_substitution");
unsigned int value = 0;
char c = next();
if (c != '_')
{
switch(c)
{
case 'a':
{
output += "std::allocator";
if (!M_inside_template_args)
{
M_function_name = "allocator";
M_name_is_template = true;
M_name_is_cdtor = false;
M_name_is_conversion_operator = false;
}
eat_current();
if (qualifiers)
qualifiers->printing_suppressed();
_GLIBCXX_DEMANGLER_RETURN;
}
case 'b':
{
output += "std::basic_string";
if (!M_inside_template_args)
{
M_function_name = "basic_string";
M_name_is_template = true;
M_name_is_cdtor = false;
M_name_is_conversion_operator = false;
}
eat_current();
if (qualifiers)
qualifiers->printing_suppressed();
_GLIBCXX_DEMANGLER_RETURN;
}
case 'd':
output += "std::iostream";
if (!M_inside_template_args)
{
M_function_name = "iostream";
M_name_is_template = true;
M_name_is_cdtor = false;
M_name_is_conversion_operator = false;
}
eat_current();
if (qualifiers)
qualifiers->printing_suppressed();
_GLIBCXX_DEMANGLER_RETURN;
case 'i':
output += "std::istream";
if (!M_inside_template_args)
{
M_function_name = "istream";
M_name_is_template = true;
M_name_is_cdtor = false;
M_name_is_conversion_operator = false;
}
eat_current();
if (qualifiers)
qualifiers->printing_suppressed();
_GLIBCXX_DEMANGLER_RETURN;
case 'o':
output += "std::ostream";
if (!M_inside_template_args)
{
M_function_name = "ostream";
M_name_is_template = true;
M_name_is_cdtor = false;
M_name_is_conversion_operator = false;
}
eat_current();
if (qualifiers)
qualifiers->printing_suppressed();
_GLIBCXX_DEMANGLER_RETURN;
case 's':
output += "std::string";
if (!M_inside_template_args)
{
M_function_name = "string";
M_name_is_template = true;
M_name_is_cdtor = false;
M_name_is_conversion_operator = false;
}
eat_current();
if (qualifiers)
qualifiers->printing_suppressed();
_GLIBCXX_DEMANGLER_RETURN;
case 't':
output += "std";
eat_current();
if (qualifiers)
qualifiers->printing_suppressed();
_GLIBCXX_DEMANGLER_RETURN;
default:
for(;; c = next())
{
if (isdigit(c))
value = value * 36 + c - '0';
else if (isupper(c))
value = value * 36 + c - 'A' + 10;
else if (c == '_')
break;
else
_GLIBCXX_DEMANGLER_FAILURE;
}
++value;
break;
}
}
eat_current();
if (value >= M_substitutions_pos.size() ||
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -