diff options
-rw-r--r-- | libcxxabi/src/cxa_demangle.cpp | 26 | ||||
-rw-r--r-- | libcxxabi/test/test_demangle.pass.cpp | 4 |
2 files changed, 17 insertions, 13 deletions
diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp index cbf04987afb..d642e67ffa8 100644 --- a/libcxxabi/src/cxa_demangle.cpp +++ b/libcxxabi/src/cxa_demangle.cpp @@ -2013,6 +2013,7 @@ struct Db { bool TagTemplates = true; bool FixForwardReferences = false; bool TryToParseTemplateArgs = true; + bool ParsingLambdaParams = false; BumpPointerAllocator ASTAllocator; @@ -2270,6 +2271,7 @@ Node *Db::parseUnnamedTypeName(NameState *) { } if (consumeIf("Ul")) { NodeArray Params; + SwapAndRestore<bool> SwapParams(ParsingLambdaParams, true); if (!consumeIf("vE")) { size_t ParamsBegin = Names.size(); do { @@ -4658,20 +4660,20 @@ Node *Db::parseTemplateParam() { if (!consumeIf('T')) return nullptr; - if (consumeIf('_')) { - if (TemplateParams.empty()) { - FixForwardReferences = true; - return make<NameType>("FORWARD_REFERENCE"); - } - return TemplateParams[0]; + size_t Index = 0; + if (!consumeIf('_')) { + if (parsePositiveInteger(&Index)) + return nullptr; + ++Index; + if (!consumeIf('_')) + return nullptr; } - size_t Index; - if (parsePositiveInteger(&Index)) - return nullptr; - ++Index; - if (!consumeIf('_')) - return nullptr; + // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter list + // are mangled as the corresponding artificial template type parameter. + if (ParsingLambdaParams) + return make<NameType>("auto"); + if (Index >= TemplateParams.size()) { FixForwardReferences = true; return make<NameType>("FORWARD_REFERENCE"); diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp index b15555965d8..e7fb0cf9990 100644 --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -29604,7 +29604,7 @@ const char* cases[][2] = {"PFvRmOE", "void (*)(unsigned long&) &&"}, {"_ZTW1x", "thread-local wrapper routine for x"}, {"_ZTHN3fooE", "thread-local initialization routine for foo"}, - {"_Z4algoIJiiiEEvZ1gEUlDpT_E_", "void algo<int, int, int>(g::'lambda'(int, int, int))"}, + // attribute abi_tag {"_Z1fB3foov", "f[abi:foo]()"}, {"_Z1fB3fooB3barv", "f[abi:foo][abi:bar]()"}, @@ -29725,6 +29725,8 @@ const char* cases[][2] = {"_ZGRDC1x1yE_", "reference temporary for [x, y]"}, {"_ZGR1bIvE2_", "reference temporary for b<void>"}, + + {"_ZZ18test_assign_throwsI20small_throws_on_copyLb0EEvvENKUlRNSt3__13anyEOT_E_clIRS0_EEDaS3_S5_", "auto void test_assign_throws<small_throws_on_copy, false>()::'lambda'(std::__1::any&, auto&&)::operator()<small_throws_on_copy&>(std::__1::any&, auto&&) const"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]); |