summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libcxxabi/src/cxa_demangle.cpp137
-rw-r--r--libcxxabi/test/test_demangle.cpp2
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]);
OpenPOWER on IntegriCloud