📄 demangle.h
字号:
M_inside_type > 20) // Rather than core dump.
_GLIBCXX_DEMANGLER_FAILURE;
++M_inside_substitution;
int saved_pos = M_pos;
substitution_st& substitution(M_substitutions_pos[value]);
M_pos = substitution.M_start_pos;
switch(substitution.M_type)
{
case type:
decode_type(output, qualifiers);
break;
case template_template_param:
decode_template_param(output, qualifiers);
break;
case nested_name_prefix:
case nested_name_template_prefix:
for (int cnt = substitution.M_number_of_prefixes; cnt > 0; --cnt)
{
if (current() == 'I')
{
if (M_template_args_need_space)
output += ' ';
M_template_args_need_space = false;
if (!decode_template_args(output))
_GLIBCXX_DEMANGLER_FAILURE;
}
else
{
if (cnt < substitution.M_number_of_prefixes)
output += "::";
if (current() == 'S')
{
if (!decode_substitution(output))
_GLIBCXX_DEMANGLER_FAILURE;
}
else if (!decode_unqualified_name(output))
_GLIBCXX_DEMANGLER_FAILURE;
}
}
if (qualifiers)
qualifiers->printing_suppressed();
break;
case unscoped_template_name:
decode_unscoped_name(output);
if (qualifiers)
qualifiers->printing_suppressed();
break;
}
M_pos = saved_pos;
--M_inside_substitution;
_GLIBCXX_DEMANGLER_RETURN;
}
// <template-param> ::= T_ # first template parameter
// ::= T <parameter-2 non-negative number> _
//
template<typename Tp, typename Allocator>
bool
session<Tp, Allocator>::decode_template_param(string_type& output,
qualifier_list<Tp, Allocator>* qualifiers)
{
_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_template_parameter");
if (current() != 'T')
_GLIBCXX_DEMANGLER_FAILURE;
unsigned int value = 0;
char c;
if ((c = next()) != '_')
{
while(isdigit(c))
{
value = value * 10 + c - '0';
c = next();
}
++value;
}
if (eat_current() != '_')
_GLIBCXX_DEMANGLER_FAILURE;
value += M_template_arg_pos_offset;
if (value >= M_template_arg_pos.size())
_GLIBCXX_DEMANGLER_FAILURE;
int saved_pos = M_pos;
M_pos = M_template_arg_pos[value];
if (M_inside_type > 20) // Rather than core dump.
_GLIBCXX_DEMANGLER_FAILURE;
++M_inside_substitution;
if (current() == 'X')
{
eat_current();
decode_expression(output);
}
else if (current() == 'L')
decode_literal(output);
else
decode_type(output, qualifiers);
--M_inside_substitution;
M_pos = saved_pos;
_GLIBCXX_DEMANGLER_RETURN;
}
template<typename Tp, typename Allocator>
bool
session<Tp, Allocator>::decode_real(string_type& output, size_t size_of_real)
{
_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_real");
unsigned long words[4]; // 32 bit per long, maximum of 128 bits.
unsigned long* word = &words[0];
int saved_pos;
store(saved_pos);
// The following assumes that leading zeroes are also included in the
// mangled name, I am not sure that is conforming to the C++-ABI, but
// it is what g++ does.
unsigned char nibble, c = current();
for(size_t word_cnt = size_of_real / 4; word_cnt > 0; --word_cnt)
{
for (int nibble_cnt = 0; nibble_cnt < 8; ++nibble_cnt)
{
// Translate character into nibble.
if (c < '0' || c > 'f')
_GLIBCXX_DEMANGLER_FAILURE;
if (c <= '9')
nibble = c - '0';
else if (c >= 'a')
nibble = c - 'a' + 10;
else
_GLIBCXX_DEMANGLER_FAILURE;
// Write nibble into word array.
if (nibble_cnt == 0)
*word = nibble << 28;
else
*word |= (nibble << (28 - 4 * nibble_cnt));
c = next();
}
++word;
}
char buf[24];
if (M_implementation_details.decode_real(buf, words, size_of_real))
{
output += buf;
_GLIBCXX_DEMANGLER_RETURN;
}
restore(saved_pos);
output += '[';
c = current();
for(size_t nibble_cnt = 0; nibble_cnt < 2 * size_of_real; ++nibble_cnt)
{
if (c < '0' || c > 'f' || (c > '9' && c < 'a'))
_GLIBCXX_DEMANGLER_FAILURE;
output += c;
c = next();
}
output += ']';
_GLIBCXX_DEMANGLER_RETURN;
}
template<typename Tp, typename Allocator>
bool
session<Tp, Allocator>::decode_literal(string_type& output)
{
_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_literal");
eat_current(); // Eat the 'L'.
if (current() == '_')
{
if (next() != 'Z')
_GLIBCXX_DEMANGLER_FAILURE;
eat_current();
if ((M_pos += decode_encoding(output, M_str + M_pos,
M_maxpos - M_pos + 1, M_implementation_details)) < 0)
_GLIBCXX_DEMANGLER_FAILURE;
}
else
{
// Special cases
if (current() == 'b')
{
if (next() == '0')
output += "false";
else
output += "true";
eat_current();
_GLIBCXX_DEMANGLER_RETURN;
}
char c = current();
if ((c == 'i' || c == 'j' || c == 'l' ||
c == 'm' || c == 'x' || c == 'y') &&
M_implementation_details.get_style_literal())
eat_current();
else if (c == 'i' &&
!M_implementation_details.get_style_literal_int())
eat_current();
else
{
output += '(';
if (!decode_type(output))
_GLIBCXX_DEMANGLER_FAILURE;
output += ')';
}
if (c >= 'd' && c <= 'g')
{
size_t size_of_real = (c == 'd') ? sizeof(double) :
((c == 'f') ? sizeof(float) :
(c == 'e') ? sizeof(long double) : 16);
if (!decode_real(output, size_of_real))
_GLIBCXX_DEMANGLER_FAILURE;
}
else if (!decode_number(output))
_GLIBCXX_DEMANGLER_FAILURE;
if (M_implementation_details.get_style_literal())
{
if (c == 'j' || c == 'm' || c == 'y')
output += 'u';
if (c == 'l' || c == 'm')
output += 'l';
if (c == 'x' || c == 'y')
output += "ll";
}
}
_GLIBCXX_DEMANGLER_RETURN;
}
// <operator-name> ::=
// nw # new
// na # new[]
// dl # delete
// da # delete[]
// ps # + (unary)
// ng # - (unary)
// ad # & (unary)
// de # * (unary)
// co # ~
// pl # +
// mi # -
// ml # *
// dv # /
// rm # %
// an # &
// or # |
// eo # ^
// aS # =
// pL # +=
// mI # -=
// mL # *=
// dV # /=
// rM # %=
// aN # &=
// oR # |=
// eO # ^=
// ls # <<
// rs # >>
// lS # <<=
// rS # >>=
// eq # ==
// ne # !=
// lt # <
// gt # >
// le # <=
// ge # >=
// nt # !
// aa # &&
// oo # ||
// pp # ++
// mm # --
// cm # ,
// pm # ->*
// pt # ->
// cl # ()
// ix # []
// qu # ?
// st # sizeof (a type)
// sz # sizeof (an expression)
// cv <type> # (cast)
// v <digit> <source-name> # vendor extended operator
//
// Symbol operator codes exist of two characters, we need to find a
// quick hash so that their names can be looked up in a table.
//
// The puzzle :)
// Shift the rows so that there is at most one character per column.
//
// A perfect solution (Oh no, it's THE MATRIX!):
// horizontal
// ....................................... offset + 'a'
// a, a||d|||||||||n||||s|||||||||||||||||||| 0
// c, || |||||||lm o||| |||||||||||||||||||| 0
// d, || a|||e|| l|| ||||||v||||||||||||| 4
// e, || ||| || || |||o|q ||||||||||||| 8
// g, || ||| || || e|| | ||||||||t|||| 15
// i, || ||| || || || | |||||||| |||x 15
// l, |e ||| || st || | |||||||| ||| -2
// m, | |i| lm || | |||||||| ||| -2
// n, a e g t| w |||||||| ||| 1
// o, | ||||o||r ||| 16
// p, | ||lm |p st| 17
// q, | u| | | 6
// r, m s | | 9
// s, t z 12
// .......................................
// ^ ^__ second character
// |___ first character
//
// Putting that solution in tables:
char const offset_table_c [1 + CHAR_MAX - CHAR_MIN ] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#if (CHAR_MIN < 0)
// Add -CHAR_MIN extra zeroes (128):
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// a b c d e f g h i j k
0, -97, 0, -97, -93, -89, 0, -82, 0, -82, 0, 0,
// l m n o p q r s t u v
-99, -99, -96, -81, -80, -91, -88, -85, 0, 0, 0,
#else
// a b c d e f g h i j k
0, 159, 0, 159, 163, 167, 0, 174, 0, 174, 0, 0,
// l m n o p q r s t u v
157, 157, 160, 175, 176, 165, 168, 171, 0, 0, 0,
#endif
// ... more zeros
};
enum xary_nt {
unary,
binary,
trinary
};
struct entry_st
{
char const* opcode;
char const* symbol_name;
xary_nt type;
};
entry_st const symbol_name_table_c[39] = {
{ "aa", "operator&&", binary },
{ "na", "operator new[]", unary },
{ "le", "operator<=", binary },
{ "ad", "operator&", unary },
{ "da", "operator delete[]", unary },
{ "ne", "operator!=", binary },
{ "mi=", "operator-", binary },
{ "ng", "operator-", unary },
{ "de", "operator*", unary },
{ "ml=", "operator*", binary },
{ "mm", "operator--", unary },
{ "cl", "operator()", unary },
{ "cm", "operator,", binary },
{ "an=", "operator&", binary },
{ "co", "operator~", binary },
{ "dl", "operator delete", unary },
{ "ls=", "operator<<", binary },
{ "lt", "operator<", binary },
{ "as=", "operator", binary },
{ "ge", "operator>=", binary },
{ "nt", "operator!", unary },
{ "rm=", "operator%", binary },
{ "eo=", "operator^", binary },
{ "nw", "operator new", unary },
{ "eq", "operator==", binary },
{ "dv=", "operator/", binary },
{ "qu", "operator?", trinary },
{ "rs=", "operator>>", binary },
{ "pl=", "operator+", binary },
{ "pm", "operator->*", binary },
{ "oo", "operator||", binary },
{ "st", "sizeof", unary },
{ "pp", "operator++", unary },
{ "or=", "operator|", binary },
{ "gt", "operator>", binary },
{ "ps", "operator+", unary },
{ "pt", "operator->", binary },
{ "sz", "sizeof", unary },
{ "ix", "operator[]", unary }
};
template<typename Tp, typename Allocator>
bool
session<Tp, Allocator>::decode_operator_name(string_type& output)
{
_GLIBCXX_DEMANGLER_DOUT_ENTERING("decode_operator_name");
char opcode0 = current();
char opcode1 = tolower(next());
register char hash;
if ((hash = offset_table_c[opcode0 - CHAR_MIN]))
{
hash += opcode1;
if (
#if (CHAR_MIN < 0)
hash >= 0 &&
#endif
hash < 39)
{
int index = static_cast<int>(static_cast<unsigned char>(hash));
entry_st entry = symbol_name_table_c[index];
if (entry.opcode[0] == opcode0 && entry.opcode[1] == opcode1
&& (opcode1 == current() || entry.opcode[2] == '='))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -