diff options
author | Chris Mihelich <cmihelic@google.com> | 2024-05-28 14:10:13 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-05-28 14:11:10 -0700 |
commit | 3ef92c6f375e71316c313a3f1a204c494cd3f762 (patch) | |
tree | 076ecdbd16bdad0e3a87947318763d97083e86d9 | |
parent | 6ec17dc63626431c6d2b0403ad4c4b9ba1ceb7d3 (diff) |
Demangle lambdas with explicit template arguments (UlTy and similar forms).
PiperOrigin-RevId: 638019038
Change-Id: I96a87e4736677df9d44520e4510e089a27372765
-rw-r--r-- | absl/debugging/internal/demangle.cc | 7 | ||||
-rw-r--r-- | absl/debugging/internal/demangle_test.cc | 42 |
2 files changed, 48 insertions, 1 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 91bea72d..1290ff65 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -861,7 +861,11 @@ static bool ParseLocalSourceName(State *state) { // <unnamed-type-name> ::= Ut [<(nonnegative) number>] _ // ::= <closure-type-name> // <closure-type-name> ::= Ul <lambda-sig> E [<(nonnegative) number>] _ -// <lambda-sig> ::= <(parameter) type>+ +// <lambda-sig> ::= <template-param-decl>* <(parameter) type>+ +// +// For <template-param-decl>* in <lambda-sig> see: +// +// https://github.com/itanium-cxx-abi/cxx-abi/issues/31 static bool ParseUnnamedTypeName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; @@ -884,6 +888,7 @@ static bool ParseUnnamedTypeName(State *state) { // Closure type. which = -1; if (ParseTwoCharToken(state, "Ul") && DisableAppend(state) && + ZeroOrMore(ParseTemplateParamDecl, state) && OneOrMore(ParseType, state) && RestoreAppend(state, copy.append) && ParseOneCharToken(state, 'E') && Optional(ParseNumber(state, &which)) && which <= std::numeric_limits<int>::max() - 2 && // Don't overflow. diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index 0195e5a7..5fd50aff 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -303,6 +303,48 @@ TEST(Demangle, LambdaRequiresRequiresExpressionContainingTwoRequirements) { EXPECT_STREQ(tmp, "$_0::operator()<>()"); } +TEST(Demangle, LambdaWithExplicitTypeArgument) { + char tmp[100]; + + // Source: + // + // template <class T> T f(T t) { + // return []<class U>(U u) { return u + u; }(t); + // } + // + // template int f<int>(int); + // + // Full LLVM demangling of the lambda call operator: + // + // auto int f<int>(int)::'lambda'<typename $T>(int):: + // operator()<int>(int) const + ASSERT_TRUE(Demangle("_ZZ1fIiET_S0_ENKUlTyS0_E_clIiEEDaS0_", + tmp, sizeof(tmp))); + EXPECT_STREQ(tmp, "f<>()::{lambda()#1}::operator()<>()"); +} + +TEST(Demangle, LambdaWithExplicitPackArgument) { + char tmp[100]; + + // Source: + // + // template <class T> T h(T t) { + // return []<class... U>(U... u) { + // return ((u + u) + ... + 0); + // }(t); + // } + // + // template int h<int>(int); + // + // Full LLVM demangling of the lambda call operator: + // + // auto int f<int>(int)::'lambda'<typename ...$T>($T...):: + // operator()<int>($T...) const + ASSERT_TRUE(Demangle("_ZZ1fIiET_S0_ENKUlTpTyDpT_E_clIJiEEEDaS2_", + tmp, sizeof(tmp))); + EXPECT_STREQ(tmp, "f<>()::{lambda()#1}::operator()<>()"); +} + // Test corner cases of boundary conditions. TEST(Demangle, CornerCases) { char tmp[10]; |