diff options
| -rw-r--r-- | libcxxabi/src/cxa_demangle.cpp | 137 | ||||
| -rw-r--r-- | libcxxabi/test/test_demangle.cpp | 2 |
2 files changed, 135 insertions, 4 deletions
diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp index aab8f0da14a..d7f383eaed0 100644 --- a/libcxxabi/src/cxa_demangle.cpp +++ b/libcxxabi/src/cxa_demangle.cpp @@ -3931,6 +3931,91 @@ public: } }; +class __lambda + : public __node +{ +public: + __lambda(__node* params, const char *number, size_t number_size) + { + __right_ = params; + __name_ = number; + __size_ = number_size; + } + + virtual size_t first_size() const + { + if (__cached_size_ == -1) + { + size_t r = 2; + r += sizeof("'lambda'")-1; + if (__right_) + r += __right_->size(); + r += __size_; + const_cast<long&>(__cached_size_) = static_cast<long>(r); + } + return static_cast<size_t>(__cached_size_); + } + virtual char* first_demangled_name(char* buf) const + { + size_t n = sizeof("'lambda") - 1; + strncpy(buf, "'lambda", n); + buf += n; + if (__size_) + { + strncpy(buf, __name_, __size_); + buf += __size_; + } + *buf++ = '\''; + *buf++ = '('; + if (__right_) + buf = __right_->get_demangled_name(buf); + *buf++ = ')'; + return buf; + } + virtual bool fix_forward_references(__node** t_begin, __node** t_end) + { + if (__right_) + return __right_->fix_forward_references(t_begin, t_end); + return true; + } +}; + +class __unnamed + : public __node +{ +public: + __unnamed(const char *number, size_t number_size) + { + __name_ = number; + __size_ = number_size; + } + + virtual size_t first_size() const + { + if (__cached_size_ == -1) + { + size_t r = 0; + r += sizeof("'unnamed'")-1; + r += __size_; + const_cast<long&>(__cached_size_) = static_cast<long>(r); + } + return static_cast<size_t>(__cached_size_); + } + virtual char* first_demangled_name(char* buf) const + { + size_t n = sizeof("'unnamed") - 1; + strncpy(buf, "'unnamed", n); + buf += n; + if (__size_) + { + strncpy(buf, __name_, __size_); + buf += __size_; + } + *buf++ = '\''; + return buf; + } +}; + class __cv_qualifiers : public __node { @@ -6874,12 +6959,55 @@ __demangle_tree::__parse_unnamed_type_name(const char* first, const char* last) { if (last - first > 2 && first[0] == 'U') { - switch (first[1]) + char type = first[1]; + switch (type) { case 't': case 'l': first += 2; - __status_ = not_yet_implemented; + + if (type == 'l') + { + __root_ = 0; + if (first[0] == 'v') + { + // void lambda + ++first; + if (first[0] == 'E') + ++first; + else + return first; + } + else + { + while (first[0] && first[0] != 'E') + { + const char *old = first; + first = __parse_type(first, last); + if (first == old) + break; + } + if (first[0] == 'E') + ++first; + else + return first; + } + } + const char *number_start = first; + first = __parse_number(first, last); + const char *number_end = first; + if (first[0] == '_') + { + ++first; + } + else + return first; + + if (type == 'l') + __make<__lambda>(__root_, number_start, static_cast<size_t>(number_end - number_start)); + else + __make<__unnamed>(number_start, static_cast<size_t>(number_end - number_start)); + break; } } @@ -10261,8 +10389,9 @@ __demangle_tree::__parse_nested_name(const char* first, const char* last) } break; case 'U': - // assert(!"__parse_nested_name U"); - // could have following <template-args> + t1 = __parse_unnamed_type_name(t0, last); + if (t1 == t0 || t1 == last) + return first; break; case 'T': t1 = __parse_template_param(t0, last); diff --git a/libcxxabi/test/test_demangle.cpp b/libcxxabi/test/test_demangle.cpp index c53ba5838e4..c8cc8530696 100644 --- a/libcxxabi/test/test_demangle.cpp +++ b/libcxxabi/test/test_demangle.cpp @@ -29565,6 +29565,8 @@ const char* cases[][2] = {"_Z13JVTLib_103270ILi1EEvPsDv2_xS1_", "void JVTLib_103270<1>(short*, long long vector[2], long long vector[2])"}, {"_ZN8platform20split_string_convertIcPFiRKSsEiSaIiESt6vectorEEjPKT_S9_S7_T0_RT3_IT1_T2_E", "unsigned int platform::split_string_convert<char, int (*)(std::string const&), int, std::allocator<int>, std::vector>(char const*, char const*, char, int (*)(std::string const&), std::vector<int, std::allocator<int> >&)"}, {"_ZN2MF12_GLOBAL__N_114WeakCallHelperINS0_15DecodeQueueImplEEEvRKN5boost8functionIFvvEEERKNS3_8weak_ptrIT_EE", "void MF::(anonymous namespace)::WeakCallHelper<MF::(anonymous namespace)::DecodeQueueImpl>(boost::function<void ()> const&, boost::weak_ptr<MF::(anonymous namespace)::DecodeQueueImpl> const&)"}, + {"_ZZN4NIds4NStr14TCStrAggregateINS0_13TCTCStrTraitsINS0_11TCStrTraitsIcNS0_17CDefaultStrParamsEEENS0_14TCStrImp_FixedIS5_Lx256EEEEEE21f_AddFromIteratorUTF8INS0_16CStrIteratorUTF8EEEvRxRKT_ENKSA_ISB_EUlmE0_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>::'lambda0'(unsigned long)::operator()(unsigned long) const"}, + {"_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"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]); |

