📄 demangle.h
字号:
} 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] == '=')) { output += entry.symbol_name; if (opcode1 != current()) output += '='; eat_current(); if (hash == 16 || hash == 17) M_template_args_need_space = true; _GLIBCXX_DEMANGLER_RETURN; } else if (opcode0 == 'c' && opcode1 == 'v') // casting operator { eat_current(); output += "operator "; if (current() == 'T') { // This is a templated cast operator. // It must be of the form "cvT_I...E". // Let M_template_arg_pos already point // to the template argument. M_template_arg_pos_offset = M_template_arg_pos.size(); M_template_arg_pos.push_back(M_pos + 3); } if (!decode_type(output)) _GLIBCXX_DEMANGLER_FAILURE; if (!M_inside_template_args) M_name_is_conversion_operator = true; _GLIBCXX_DEMANGLER_RETURN; } } } _GLIBCXX_DEMANGLER_FAILURE; } // // <expression> ::= <unary operator-name> <expression> // ::= <binary operator-name> <expression> <expression> // ::= <trinary operator-name> <expression> <expression> <expression> // ::= st <type> // ::= <template-param> // ::= sr <type> <unqualified-name> # dependent name // ::= sr <type> <unqualified-name> <template-args> # dependent template-id // ::= <expr-primary> // // <expr-primary> ::= L <type> <value number> E # integer literal // ::= L <type> <value float> E # floating literal // ::= L <mangled-name> E # external name // template<typename Tp, typename Allocator> bool session<Tp, Allocator>::decode_expression(string_type& output) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -