📄 demangle.h
字号:
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() || 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -