Commit 3ef92c6f by Chris Mihelich Committed by Copybara-Service

Demangle lambdas with explicit template arguments (UlTy and similar forms).

PiperOrigin-RevId: 638019038
Change-Id: I96a87e4736677df9d44520e4510e089a27372765
parent 6ec17dc6
...@@ -861,7 +861,11 @@ static bool ParseLocalSourceName(State *state) { ...@@ -861,7 +861,11 @@ static bool ParseLocalSourceName(State *state) {
// <unnamed-type-name> ::= Ut [<(nonnegative) number>] _ // <unnamed-type-name> ::= Ut [<(nonnegative) number>] _
// ::= <closure-type-name> // ::= <closure-type-name>
// <closure-type-name> ::= Ul <lambda-sig> E [<(nonnegative) number>] _ // <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) { static bool ParseUnnamedTypeName(State *state) {
ComplexityGuard guard(state); ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false; if (guard.IsTooComplex()) return false;
...@@ -884,6 +888,7 @@ static bool ParseUnnamedTypeName(State *state) { ...@@ -884,6 +888,7 @@ static bool ParseUnnamedTypeName(State *state) {
// Closure type. // Closure type.
which = -1; which = -1;
if (ParseTwoCharToken(state, "Ul") && DisableAppend(state) && if (ParseTwoCharToken(state, "Ul") && DisableAppend(state) &&
ZeroOrMore(ParseTemplateParamDecl, state) &&
OneOrMore(ParseType, state) && RestoreAppend(state, copy.append) && OneOrMore(ParseType, state) && RestoreAppend(state, copy.append) &&
ParseOneCharToken(state, 'E') && Optional(ParseNumber(state, &which)) && ParseOneCharToken(state, 'E') && Optional(ParseNumber(state, &which)) &&
which <= std::numeric_limits<int>::max() - 2 && // Don't overflow. which <= std::numeric_limits<int>::max() - 2 && // Don't overflow.
......
...@@ -303,6 +303,48 @@ TEST(Demangle, LambdaRequiresRequiresExpressionContainingTwoRequirements) { ...@@ -303,6 +303,48 @@ TEST(Demangle, LambdaRequiresRequiresExpressionContainingTwoRequirements) {
EXPECT_STREQ(tmp, "$_0::operator()<>()"); 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 corner cases of boundary conditions.
TEST(Demangle, CornerCases) { TEST(Demangle, CornerCases) {
char tmp[10]; char tmp[10];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment