diff options
-rw-r--r-- | include/cxa_demangle.h | 1 | ||||
-rw-r--r-- | src/cxa_demangle.cpp | 81 | ||||
-rw-r--r-- | test/test_demangle.cpp | 1 |
3 files changed, 83 insertions, 0 deletions
diff --git a/include/cxa_demangle.h b/include/cxa_demangle.h index 46dc982..1e373b3 100644 --- a/include/cxa_demangle.h +++ b/include/cxa_demangle.h @@ -129,6 +129,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_block_invoke(const char*, const char*); const char* __parse_unresolved_qualifier_level(const char*, const char*); const char* __parse_vector_type(const char*, const char*); const char* __parse_hex_number(const char*, const char*, unsigned long long&); diff --git a/src/cxa_demangle.cpp b/src/cxa_demangle.cpp index c1e1260..aad7848 100644 --- a/src/cxa_demangle.cpp +++ b/src/cxa_demangle.cpp @@ -149,6 +149,37 @@ void display(__node* x, int indent = 0) #endif +class __block_invoke + : public __node +{ + static const ptrdiff_t n = sizeof("invocation function for block in ") - 1; +public: + __block_invoke(__node* type) + { + __right_ = type; + } + + virtual size_t first_size() const + { + if (__cached_size_ == -1) + const_cast<long&>(__cached_size_) = n + static_cast<long>(__right_->size()); + return static_cast<size_t>(__cached_size_); + } + virtual char* first_demangled_name(char* buf) const + { + strncpy(buf, "invocation function for block in ", n); + return __right_->get_demangled_name(buf+n); + } + virtual __node* base_name() const + { + return __right_->base_name(); + } + virtual bool fix_forward_references(__node** t_begin, __node** t_end) + { + return __right_->fix_forward_references(t_begin, t_end); + } +}; + class __vtable : public __node { @@ -10836,6 +10867,41 @@ __demangle_tree::__parse_dot_suffix(const char* first, const char* last) return first; } +// _block_invoke +// _block_invoke<decimal-digit>+ +// _block_invoke_<decimal-digit>+ + +const char* +__demangle_tree::__parse_block_invoke(const char* first, const char* last) +{ + if (last - first >= 13) + { + const char test[] = "_block_invoke"; + const char* t = first; + for (int i = 0; i < 13; ++i, ++t) + { + if (*t != test[i]) + return first; + } + if (t != last) + { + if (*t == '_') + { + // must have at least 1 decimal digit + if (++t == last || !isdigit(*t)) + return first; + ++t; + } + // parse zero or more digits + while (t != last && isdigit(*t)) + ++t; + } + if (__make<__block_invoke>(__root_)) + first = t; + } + return first; +} + // <encoding> ::= <function name> <bare-function-type> // ::= <data name> // ::= <special-name> @@ -10896,6 +10962,9 @@ __demangle_tree::__parse_encoding(const char* first, const char* last) return first; } +// <block-involcaton-function> ___Z<encoding>_block_invoke +// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+ +// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+ // <mangled-name> ::= _Z<encoding> // ::= <type> @@ -10916,6 +10985,18 @@ __demangle_tree::__parse() if (t != __mangled_name_begin_+2 && t != __mangled_name_end_ && *t == '.') t = __parse_dot_suffix(t, __mangled_name_end_); } + else if (__mangled_name_end_ - __mangled_name_begin_ >= 4 && + __mangled_name_begin_[0] == '_' && + __mangled_name_begin_[1] == '_' && + __mangled_name_begin_[2] == '_' && + __mangled_name_begin_[3] == 'Z') + { + t = __parse_encoding(__mangled_name_begin_+4, __mangled_name_end_); + if (t != __mangled_name_begin_+4 && t != __mangled_name_end_) + t = __parse_block_invoke(t, __mangled_name_end_); + else + t = __mangled_name_begin_; + } else t = __parse_type(__mangled_name_begin_, __mangled_name_end_); if (t == __mangled_name_end_ && __root_) diff --git a/test/test_demangle.cpp b/test/test_demangle.cpp index f267de0..5c44e9a 100644 --- a/test/test_demangle.cpp +++ b/test/test_demangle.cpp @@ -29569,6 +29569,7 @@ const char* cases[][2] = {"_ZZN4NIds4NStr14TCStrAggregateINS0_13TCTCStrTraitsINS0_11TCStrTraitsIcNS0_17CDefaultStrParamsEEENS0_14TCStrImp_FixedIS5_Lx256EEEEEE21f_AddFromIteratorUTF8INS0_16CStrIteratorUTF8EEEvRxRKT_ENKSA_ISB_EUt0_clEm", "void NIds::NStr::TCStrAggregate<NIds::NStr::TCTCStrTraits<NIds::NStr::TCStrTraits<char, NIds::NStr::CDefaultStrParams>, NIds::NStr::TCStrImp_Fixed<NIds::NStr::TCStrTraits<char, NIds::NStr::CDefaultStrParams>, 256ll> > >::f_AddFromIteratorUTF8<NIds::NStr::CStrIteratorUTF8>(long long&, NIds::NStr::CStrIteratorUTF8 const&)::NIds::NStr::TCStrAggregate<NIds::NStr::TCTCStrTraits<NIds::NStr::TCStrTraits<char, NIds::NStr::CDefaultStrParams>, NIds::NStr::TCStrImp_Fixed<NIds::NStr::TCStrTraits<char, NIds::NStr::CDefaultStrParams>, 256ll> > >::f_AddFromIteratorUTF8<NIds::NStr::CStrIteratorUTF8>::'unnamed0'::operator()(unsigned long) const"}, {"_ZNK3com9markzware2js11cJSArgumentcvRKT_I8cMyClassEEv", "com::markzware::js::cJSArgument::operator cMyClass const &<cMyClass>() const"}, {"_ZNKSt3__110__function6__funcIZN4DLCL8DLFutureIP15AnalysenManagerE3setINS_8functionIFS5_vEEEJEEEvT_DpOT0_EUlvE_NS_9allocatorISF_EEFvvEE7__cloneEv", "std::__1::__function::__func<void DLCL::DLFuture<AnalysenManager*>::set<std::__1::function<AnalysenManager* ()> >(std::__1::function<AnalysenManager* ()>)::'lambda'(), std::__1::allocator<void DLCL::DLFuture<AnalysenManager*>::set<std::__1::function<AnalysenManager* ()> >(std::__1::function<AnalysenManager* ()>)::'lambda'()>, void ()>::__clone() const"}, + {"___ZN19URLConnectionClient33_clientInterface_cancelConnectionEP16dispatch_queue_sU13block_pointerFvvE_block_invoke14", "invocation function for block in URLConnectionClient::_clientInterface_cancelConnection(dispatch_queue_s*, void ()() block_pointer)"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]); |