diff options
-rw-r--r-- | include/cxa_demangle.h | 1 | ||||
-rw-r--r-- | src/cxa_demangle.cpp | 115 | ||||
-rw-r--r-- | test/test_demangle.cpp | 4 |
3 files changed, 80 insertions, 40 deletions
diff --git a/include/cxa_demangle.h b/include/cxa_demangle.h index 863e0bc..bb4ce60 100644 --- a/include/cxa_demangle.h +++ b/include/cxa_demangle.h @@ -127,6 +127,7 @@ private: const char* __parse_pack_expansion(const char*, const char*); const char* __parse_sizeof_function_param_pack_expr(const char*, const char*); const char* __parse_dot_suffix(const char*, const char*); + const char* __parse_unresolved_qualifier_level(const char*, const char*); const char* __parse_hex_number(const char*, const char*, unsigned long long&); template <class _Tp> bool __make(); diff --git a/src/cxa_demangle.cpp b/src/cxa_demangle.cpp index f455329..1b6da07 100644 --- a/src/cxa_demangle.cpp +++ b/src/cxa_demangle.cpp @@ -11308,68 +11308,107 @@ __demangle_tree::__parse_unresolved_type(const char* first, const char* last) return first; } +// <unresolved-qualifier-level> ::= <source-name> [ <template-args> ] + +const char* +__demangle_tree::__parse_unresolved_qualifier_level(const char* first, const char* last) +{ + if (first != last) + { + const char* t = __parse_source_name(first, last); + if (t != first) + first = __parse_template_args(t, last); + } + return first; +} + // <unresolved-name> -// ::= sr <name> <base-unresolved-name> # extension, subtly different than srN ... -// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x -// # T::N::x /decltype(p)::N::x +// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name> // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name> // # A::x, N::y, A<T>::z; "gs" means leading "::" -// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name> +// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x +// # T::N::x /decltype(p)::N::x +// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name> const char* __demangle_tree::__parse_unresolved_name(const char* first, const char* last) { if (last - first > 2) { - if (first[0] == 's' && first[1] == 'r') + const char* t = first; + bool global = false; + if (t[0] == 'g' && t[1] == 's') { - const char* t = __parse_name(first+2, last); - if (t == first+2) - t = __parse_unresolved_type(first+2, last); - if (t != first+2) - { - __node* name = __root_; - const char* t2 = __parse_base_unresolved_name(t, last); - if (t2 != t && __make<__unresolved_name>(name, __root_)) - first = t2; - } + global = true; + t += 2; } - else + const char* t2 = __parse_base_unresolved_name(t, last); + if (t2 != t) { - const char* t = first; - bool global = false; - if (t[0] == 'g' && t[1] == 's') + if (__make<__unresolved_name>(global, (__node*)0, __root_)) + first = t2; + } + else if (last - t > 2 && t[0] == 's' && t[1] == 'r') + { + if (!global && t[2] == 'N') { - global = true; - t += 2; + t2 = __parse_unresolved_type(t+3, last); + if (t2 != t+3 && t2 != last) + { + t = __parse_template_args(t2, last); + if (t == last) + return first; + __node* name = __root_; + while (*t != 'E') + { + t2 = __parse_unresolved_qualifier_level(t, last); + if (t2 == t || t2 == last) + return first; + if (!__make<__nested_delimeter>(name, __root_)) + return first; + name = __root_; + t = t2; + } + t2 = __parse_base_unresolved_name(++t, last); + if (t2 != t && __make<__unresolved_name>(false, name, __root_)) + first = t2; + } } - if (last - t > 2) + else { - const char* t2; - __node* name = NULL; - if (t[0] == 's' && t[1] == 'r') + if (!global) { - t += 2; - t2 = __parse_simple_id(t, last); - if (t2 == t || t2 == last) - return first; - name = __root_; - while (*t2 != 'E') + t2 = __parse_unresolved_type(t+2, last); + if (t2 != t+2) { t = t2; - t2 = __parse_simple_id(t, last); - if (t2 == t) + __node* name = __root_; + t2 = __parse_base_unresolved_name(t, last); + if (t2 != t && __make<__unresolved_name>(false, name, __root_)) + return t2; + return first; + } + } + t2 = __parse_unresolved_qualifier_level(t+2, last); + if (t2 != t+2 && t2 != last) + { + __node* name = __root_; + t = t2; + while (*t != 'E') + { + t2 = __parse_unresolved_qualifier_level(t, last); + if (t2 == t || t2 == last) return first; if (!__make<__nested_delimeter>(name, __root_)) return first; name = __root_; + t = t2; } - t = t2+1; + t2 = __parse_base_unresolved_name(++t, last); + if (t2 != t && __make<__unresolved_name>(global, name, __root_)) + first = t2; } - t2 = __parse_base_unresolved_name(t, last); - if (t2 != t && __make<__unresolved_name>(global, name, __root_)) - first = t2; } } } @@ -14696,7 +14735,7 @@ __demangle_tree::__parse_encoding(const char* first, const char* last) const char* t = __parse_name(first, last); if (t != first) { - if (t != last && *t != 'E') + if (t != last && *t != 'E' && *t != '.') { __node* name = __root_; bool has_return = name->ends_with_template() && diff --git a/test/test_demangle.cpp b/test/test_demangle.cpp index 47819c2..4802544 100644 --- a/test/test_demangle.cpp +++ b/test/test_demangle.cpp @@ -29500,8 +29500,8 @@ const char* cases[][2] = {"_ZplRK1YRA100_P1X", "operator+(Y const&, X* (&) [100])"}, {"_Z1fno", "f(__int128, unsigned __int128)"}, {"_Z1fM1SKFvvE", "f(void (S::*)() const)"}, - {"_Z3ft7IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv", "__enable_if<__is_scalar<int>::__value, void>::__type ft7<int>()"}, - {"_Z3ft7IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv", "__enable_if<__is_scalar<void*>::__value, void>::__type ft7<void*>()"}, + {"_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv", "__enable_if<__is_scalar_type<int>::__value, void>::__type ft7<int>()"}, + {"_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv", "__enable_if<__is_scalar_type<void*>::__value, void>::__type ft7<void*>()"}, {"_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsrNS_11__is_scalarIT_EE7__valueEvE6__typeEv", "PR5796::__enable_if<!(PR5796::__is_scalar<int>::__value), void>::__type PR5796::__fill_a<int>()"}, {"_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i", "void Expressions::f1<1>(int (*) [(-(1)) + (2)])"}, {"_ZN11Expressions2f2ILi1EEEvPApsT__i", "void Expressions::f2<1>(int (*) [+(1)])"}, |